Raku pop() order of execution - raku

Isn't order of execution generally from left to right in Raku?
my #a = my #b = [9 , 3];
say (#a[1] - #a[0]) == (#b[1] R- #b[0]); # False {as expected}
say (#a.pop() - #a.pop()) == (#b.pop() R- #b.pop()); # True {Huh?!?}
This is what I get in Rakudo(tm) v2020.12 and 2021.07.
The first 2 lines make sense, but the third I can not fathom.

It is.
But you should realize that the minus infix operator is just a subroutine under the hood, taking 2 parameters that are evaluated left to right. So when you're saying:
$a - $b
you are in fact calling the infix:<-> sub:
infix:<->($a,$b);
The R meta-operator basically creates a wrap around the infix:<-> sub that reverses the arguments:
my &infix:<R->($a,$b) = &infix:<->.wrap: -> $a, $b { nextwith $b, $a }
So, if you do a:
$a R- $b
you are in fact doing a:
infix:<R->($a,$b)
which is then basically a:
infix:<->($b,$a)
Note that in the call to infix:<R-> in your example, $a become 3, and $b becomes 9 because the order of the arguments is processed left to right. This then calls infix:<->(3,9), producing the -6 value that you would also get without the R.
It may be a little counter-intuitive, but I consider this behaviour as correct. Although the documentation could probably use some additional explanation on this behaviour.

Let me emulate what I assumed was happening in line 3 of my code prefaced with #a is the same as #b is 9, 3 (big number then little number)
(#a.pop() - #a.pop()) == (#b.pop() R- #b.pop())
(3 - 9) == (3 R- 9)
( -6 ) == ( 6 )
False
...That was my expectation. But what raku seems to be doing is
(#a.pop() - #a.pop()) == (#b.pop() R- #b.pop())
#R meta-op swaps 1st `#b.pop()` with 2nd `#b.pop()`
(#a.pop() - #a.pop()) == (#b.pop() - #b.pop())
(3 - 9) == (3 - 9)
( -6 ) == ( -6 )
True
The R in R- swaps functions first, then calls the for values. Since they are the same function, the R in R- has no practical effect.
Side Note: In fuctional programming a 'pure' function will return the same value every time you call it with the same parameters. But pop is not 'pure'. Every call can produce different results. It needs to be used with care.

The R meta op not only reverses the operator, it will also reverse the order in which the operands will be evaluated.
sub term:<a> { say 'a'; '3' }
sub term:<b> { say 'b'; '9' }
say a ~ b;
a
b
ab
Note that a happened first.
If we use R, then b happens first instead.
say a R~ b;
b
a
ba
The problem is that in your code all of the pop calls are getting their data from the same source.
my #data = < a b a b >;
sub term:<l> { my $v = #data.shift; say "l=$v"; return $v }
sub term:<r> { my $v = #data.shift; say "r=$v"; return $v }
say l ~ r;
l=a
r=b
ab
say l R~ r;
r=a
l=b
ab
A way to get around that is to use the reduce meta operator with a list
[-](#a.pop, #a.pop) == [R-](#a.pop, #a.pop)
Or in some other way make sure the pop operations happen in the order you expect.
You could also just use the values directly from the array without using pop.
[-]( #a[0,1] ) == [R-]( #a[2,3] )

Let me emulate what happens by writing the logic one way for #a then manually reversing the operands for #b instead of using R:
my #a = my #b = [9 , 3];
sub apop { #a.pop }
sub bpop { #b.pop }
say apop - apop; # -6
say bpop - bpop; # -6 (operands *manually* reversed)
This not only appeals to my sense of intuition about what's going on, I'm thus far confused why you were confused and why Liz has said "It may be a little counter-intuitive" and you've said it is plain unintuitive!

Related

i am new, program gives error "there are no type variables left in list"

How the game works is that there is a 3-digit number, and you have to guess it. If you guess a digit in the right spot, you get a strike, and if you guess a digit but in the wrong spot you get a ball. I've coded it like this.
x = random.randint(1, 9)
y = random.randint(1, 9)
z = random.randint(1, 9)
userguessunlisted = input('What number do you want to guess?')
numbertoguess = list[x, y, z]
userguess = list(userguessunlisted)
b = 0
s = 0
while 0 == 0:
if userguess[0] == numbertoguess[0]:
s = s + 1
if userguess[0] == numbertoguess[1]:
b = b + 1
if userguess[0] == numbertoguess[2]:
b = b + 1
if userguess[1] == numbertoguess[0]:
b = b + 1
if userguess[1] == numbertoguess[1]:
s = s + 1
if userguess[1] == numbertoguess[2]:
b = b + 1
if userguess[2] == numbertoguess[0]:
b = b + 1
if userguess[2] == numbertoguess[1]:
b = b + 1
if userguess[2] == numbertoguess[2]:
s = s + 1
print(s + "S", b + "B")
if s != 3:
b = 0
s = 0
else:
print('you win!')
break
When you said list[x, y, z] on line 5, you used square brackets, which python interprets to be a type annotation. For example, if I wanted to specify that a variable is a list of ints, I could say
my_list_of_ints: list[int] = [1, 2, 3]
I think what you meant to do is create a new list from x, y, and z. One way to do this is
numbertoguess = list([x, y, z])
which is probably what you meant to write. This is valid because the list function takes an iterable as its one and only argument.
However, the list portion is redundant; square brackets on the right-hand side of an assignment statement already means "create a list with this content," so instead you should simply say
numbertoguess = [x, y, z]
A few other notes:
input will return a string, but you are comparing that string to integers further down, so none of the comparisons will ever be true. What you want to say is something like the following:
while True:
try:
userguessunlisted = int(input('What number do you want to guess?'))
except:
continue
break
What this code does is attempts to parse the string returned from input into an int. If it fails to do so, which would happen if the user inputted something other than a valid integer, an exception would be thrown, and the except block would be entered. continue means go to the top of the loop, so the input line runs repeatedly until a valid int is entered. When that happens, the except block is skipped, so break runs, which means "exit the loop."
userguessunlisted is only ever going to contain 1 number as written, so userguess will be a list of length 1, and all of the comparisons using userguess[1] and userguess[2] will throw an IndexError. Try to figure out how to wrap the code from (1) in another loop to gather multiple guesses from the user. Hint: use a for loop with range.
It might also be that you meant for the user to input a 3-digit number all at once. In that case, you can use a list comprehension to grab each character from the input and parse it into a separate int. This is probably a bit complicated for a beginner, so I'll help you out:
[int(char) for char in input('What number do you want to guess?')]
print(s + "S", b + "B") will throw TypeError: unsupported operand type(s) for +: 'int' and 'str'. There are lots of ways to combine non-string types with strings, but the most modern way is using f-strings. For example, to combine s with "S", you can say f"{s}S".
When adding some amount to a variable, instead of saying e.g. b = b + 1, you can use the += operator to more concisely say b += 1.
It's idiomatic in python to use snake_case for variables and Pascal case for classes. So instead of writing e.g. numbertoguess, you should use number_to_guess. This makes your code more readable and familiar to other python programmers.
Happy coding!

OCaml : Infinite Loop

I am trying to do this simple while loop but it's not working. The compiler is not giving any type of error or warning but when i try to run my function it ends up in an infinite loop:
let example x =
let k = ref x in
while (!k > 42) do
if ( (!k mod 5) == 0) then (
k:= !k/2
);
done;
if(!k<42) then (
Printf.printf "k is less than 42"
);
if(!k == 42) then (
Printf.printf "k is equal to 42"
)
;;
Well, your loop only modifies !k when !k mod 5 = 0. If !k isn't divisible by 5, it will never change in value. This suggests that the loop will either run 0 times or will run an infinite number of times.
You don't show any calls to example, but any call where you pass a value > 42 and not a multiple of 5 should loop infinitely it seems to me.
By the way, this is what #user2864740 was trying to point out. 43 is a value > 42 that's not divisible by 5.
(As a side comment, you should use = to compare values for equality. The == operator in OCaml is useful in limited cases. This often causes problems for people coming from other languages.)

Destructuring a list with equations in maxima

Say that I have the following list of equations:
list: [x=1, y=2, z=3];
I use this pattern often to have multiple return values from a function. Kind of of like how you would use an object, in for example, javascript. However, in javascript, I can do things like this. Say that myFunction() returns the object {x:1, y:2, z:3}, then I can destructure it with this syntax:
let {x,y,z} = myFunction();
And now x,y,z are assigned the values 1,2,3 in the current scope.
Is there anything like this in maxima? Now I use this:
x: subst(list, x);
y: subst(list, y);
z: subst(list, z);
How about this. Let l be a list of equations of the form somesymbol = somevalue. I think all you need is:
map (lhs, l) :: map (rhs, l);
Here map(lhs, l) yields the list of symbols, and map(rhs, l) yields the list of values. The operator :: means evaluate the left-hand side and assign the right-hand side to it. When the left-hand side is a list, then Maxima assigns each value on the right-hand side to the corresponding element on the left.
E.g.:
(%i1) l : [a = 12, b = 34, d = 56] $
(%i2) map (lhs, l) :: map (rhs, l);
(%o2) [12, 34, 56]
(%i3) values;
(%o3) [l, a, b, d]
(%i4) a;
(%o4) 12
(%i5) b;
(%o5) 34
(%i6) d;
(%o6) 56
You can probably achieve it and write a function that could be called as f(['x, 'y, 'z], list); but you will have to be able to make some assignments between symbols and values. This could be done by writing a tiny ad hoc Lisp function being:
(defun $assign (symb val) (set symb val))
You can see how it works (as a first test) by first typing (form within Maxima):
:lisp (defun $assign (symb val) (set symb val))
Then, use it as: assign('x, 42) which should assign the value 42 to the Maxima variable x.
If you want to go with that idea, you should write a tiny Lisp file in your ~/.maxima directory (this is a directory where you can put your most used functions); call it for instance myfuncs.lisp and put the function above (without the :lisp prefix); then edit (in the very same directory) your maxima-init.mac file, which is read at startup and add the two following things:
add a line containing load("myfuncs.lisp"); before the following part;
define your own Maxima function (in plain Maxima syntax with no need to care about Lisp). Your function should contain some kind of loop for performing all assignments; now you could use the assign(symbol, value) function for each variable.
Your function could be something like:
f(vars, l) := for i:1 thru length(l) do assign(vars[i], l[i]) $
which merely assign each value from the second argument to the corresponding symbol in the first argument.
Thus, f(['x, 'y], [1, 2]) will perform the expected assigments; of course you can start from that for doing more precisely what you need.

Perl6-ish expression for the bits of an integer

I've been trying to exercise my Perl 6 chops by looking at some golfing problems. One of them involved extracting the bits of an integer. I haven't been able to come up with a succinct way to write such an expression.
My "best" tries so far follow, using 2000 as the number. I don't care whether the most or least significant bit comes first.
A numeric expression:
map { $_ % 2 }, (2000, * div 2 ... * == 0)
A recursive anonymous subroutine:
{ $_ ?? ($_ % 2, |&?BLOCK($_ div 2)) !! () }(2000)
Converting to a string:
2000.fmt('%b') ~~ m:g/./
Of these, the first feels cleanest to me, but it would be really nice to be able to generate the bits in a single step, rather than mapping over an intermediate list.
Is there a cleaner, shorter, and/or more idiomatic way to get the bits, using a single expression? (That is, without writing a named function.)
The easiest way would be:
2000.base(2).comb
The .base method returns a string representation, and .comb splits it into characters - similar to your third method.
An imperative solution, least to most significant bit:
my $i = 2000; say (loop (; $i; $i +>= 1) { $i +& 1 })
The same thing rewritten using hyperoperators on a sequence:
say (2000, * +> 1 ...^ !*) >>+&>> 1
An alternative that is more useful when you need to change the base to anything above 36, is to use polymod with an infinite list of that base.
Most of the time you will have to reverse the order though.
say 2000.polymod(2 xx *);
# (0 0 0 0 1 0 1 1 1 1 1)
say 2000.polymod(2 xx *).reverse;
say [R,] 2000.polymod(2 xx*);
# (1 1 1 1 1 0 1 0 0 0 0)

Why do most programming languages only have binary equality comparison operators?

In natural languages, we would say "some color is a primary color if the color is red, blue, or yellow."
In every programming language I've seen, that translates into something like:
isPrimaryColor = someColor == "Red" or someColor == "Blue" or someColor == "Yellow"
Why isn't there a syntax that more closely matches the English sentence. After all, you wouldn't say "some color is a primary color if that color is red, or that color is blue, or that color is yellow."
I realize simply isPrimaryColor = someColor == ("Red" or "Blue" or "Yellow") because instead of Red Blue and Yellow they could be boolean statement in which case boolean logic applies, but what about something like:
isPrimaryColor = someColor ( == "Red" or == "Blue" or == "Yellow")
As an added bonus that syntax would allow for more flexibility, say you wanted to see if a number is between 1 and 100 or 1000 and 2000, you could say:
someNumber ((>= 1 and <=100) or (>=1000 and <=2000))
Edit:
Very interesting answers, and point taken that I should learn more languages. After reading through the answers I agree that for strictly equality comparison something similar to set membership is a clear and concise way of expressing the same thing (for languages that have language support for concise inline lists or sets and testing membership)
One issues that came up is that if the value to compare is the result of an expensive calculation a temporary variable would need to be (well, should be) created. The other issue is that there may be different evaluations that need to be checked, such as "the result of some expensive calculation should be prime and between 200 and 300"
These scenarios are also covered by more functional languages (though depending on the language may not be more concise), or really any language that can take a function as a parameter. For instance the previous example could be
MeetsRequirements(GetCalculatedValue(), f(x):x > 200, f(x):x < 300, IsPrime)
I think that most people consider something like
isPrimaryColor = ["Red", "Blue", "Yellow"].contains(someColor)
to be sufficiently clear that they don't need extra syntax for this.
In python you can do something like this:
color = "green"
if color in ["red", "green", "blue"]:
print 'Yay'
It is called in operator, which tests for set membership.
In perl 6 you could do this with junctions:
if $color eq 'Red'|'Blue'|'Green' {
doit()
}
Alternately you could do it with the smart match operator (~~). The following is roughly equivalent to python's if value in list: syntax, except that ~~ does a lot more in other contexts.
if ($color ~~ qw/Red Blue Green/) {
doit()
}
The parens also make it valid perl 5 (>=5.10); in perl 6 they're optional.
In Haskell, it is easy to define a function to do this:
matches x ps = foldl (||) False $ map (\ p -> p x) ps
This function takes a value list of predicates (of type a -> Bool) and returns True if any of the the predicates match the value.
This allows you to something like this:
isMammal m = m `matches` [(=="Dog"), (=="Cat"), (=="Human")]
The nice thing is that it doesn't have to just be equality, you can use anything with the correct type:
isAnimal a = a `matches` [isMammal, (=="Fish"), (=="Bird")]
Ruby
Contained in list:
irb(main):023:0> %w{red green blue}.include? "red"
=> true
irb(main):024:0> %w{red green blue}.include? "black"
=> false
Numeric Range:
irb(main):008:0> def is_valid_num(x)
irb(main):009:1> case x
irb(main):010:2> when 1..100, 1000..2000 then true
irb(main):011:2> else false
irb(main):012:2> end
irb(main):013:1> end
=> nil
irb(main):014:0> is_valid_num(1)
=> true
irb(main):015:0> is_valid_num(100)
=> true
irb(main):016:0> is_valid_num(101)
=> false
irb(main):017:0> is_valid_num(1050)
=> true
So far, nobody has mentioned SQL. It has what you are suggesting:
SELECT
employee_id
FROM
employee
WHERE
hire_date BETWEEN '2009-01-01' AND '2010-01-01' -- range of values
AND employment_type IN ('C', 'S', 'H', 'T') -- list of values
COBOL uses 88 levels to implement named values, named groups of values
and named ranges of values.
For example:
01 COLOUR PIC X(10).
88 IS-PRIMARY-COLOUR VALUE 'Red', 'Blue', 'Yellow'.
...
MOVE 'Blue' TO COLOUR
IF IS-PRIMARY-COLOUR
DISPLAY 'This is a primary colour'
END-IF
Range tests are covered as follows:
01 SOME-NUMBER PIC S9(4) BINARY.
88 IS-LESS-THAN-ZERO VALUE -9999 THRU -1.
88 IS-ZERO VALUE ZERO.
88 IS-GREATER-THAN-ZERO VALUE 1 THRU 9999.
...
MOVE +358 TO SOME-NUMBER
EVALUATE TRUE
WHEN IS-LESS-THAN-ZERO
DISPLAY 'Negative Number'
WHEN IS-ZERO
DISPLAY 'Zero'
WHEN IS-GREATER-THAN-ZERO
DISPLAY 'Positive Number'
WHEN OTHER
DISPLAY 'How the heck did this happen!'
END-EVALUATE
I guess this all happened because COBOL was supposed to emulate English
to some extent.
You'll love Perl 6 because it has:
chaining comparison operators:
(1 <= $someNumber <= 100) || (1000 <= $someNumber <= 2000))
junctive operators:
$isPrimaryColor = $someColor ~~ "Red" | "Blue" | "Yellow"
And you can combine both with ranges:
$someNumber ~~ (1..100) | (1000..2000)
Python actually gives you the ability to do the last thing quite well:
>>> x=5
>>> (1<x<1000 or 2000<x<3000)
True
In Python you can say ...
isPrimaryColor = someColor in ('Red', 'Blue', 'Yellow')
... which I find more readable than your (== "Red" or == "Blue") syntax. There's a few reasons to add syntax support for a language feature:
Efficiency: Not a reason here, since there's no speed improvement.
Functionality: Also not a concern; there's nothing you can do in the new syntax that you can't do in the old.
Legibility: Most languages handle the case where you're checking the equality of multiple values just fine. In other cases (e.g., someNumber (> 1 and < 10)) it might be more useful, but even then it doesn't buy you much (and Python allows you to say 1 < someNumber < 10, which is even clearer).
So it's not clear the proposed change is particularly helpful.
My guess would be that languages are designed by force of habit. Early languages only would have had binary comparison operators because they are simpler to implement. Everyone got used to saying (x > 0 and x < y) until language designers didn't ever bother to support the common form in mathematics, (0 < x < y).
In most languages a comparison operator returns a boolean type. In the case of 0 < x < y, if this is interpreted as (0 < x) < y it would be meaningless, since < does not make sense for comparing booleans. Therefore, a new compiler could interpret 0 < x < y as tmp:=x, 0 < tmp && tmp < y without breaking backward compatibility. In the case of x == y == z, however, if the variables are already booleans, it is ambiguous whether this means x == y && y == z or (x == y) == z.
In C# I use the following extension method so that you can write someColor.IsOneOf("Red", "Blue", "Yellow"). It is less efficient than direct comparison (what with the array, loop, Equals() calls and boxing if T is a value type), but it sure is convenient.
public static bool IsOneOf<T>(this T value, params T[] set)
{
object value2 = value;
for (int i = 0; i < set.Length; i++)
if (set[i].Equals(value2))
return true;
return false;
}
Icon has the facility you describe.
if y < (x | 5) then write("y=", y)
I rather like that aspect of Icon.
In C#:
if ("A".IsIn("A", "B", "C"))
{
}
if (myColor.IsIn(colors))
{
}
Using these extensions:
public static class ObjectExtenstions
{
public static bool IsIn(this object obj, params object [] list)
{
foreach (var item in list)
{
if (obj == item)
{
return true;
}
}
return false;
}
public static bool IsIn<T>(this T obj, ICollection<T> list)
{
return list.Contains(obj);
}
public static bool IsIn<T>(this T obj, IEnumerable<T> list)
{
foreach (var item in list)
{
if (obj == item)
{
return true;
}
}
return false;
}
}
You'll have to go a bit down the abstraction layer to find out the reason why. x86's comparison/jump instructions are binary (since they can be easily computed in a few clock cycles), and that's the way things have been.
If you want, many languages offer an abstraction for that. In PHP, for example you could use:
$isPrimaryColor = in_array($someColor, array('Red', 'White', 'Blue'));
I don't see an Objective-C answer yet. Here is one:
BOOL isPRimaryColour = [[NSSet setWithObjects: #"red", #"green", #"blue", nil] containsObject: someColour];
The question is reasonable, and I wouldn't regard the change as syntactic sugar. If the value being compared is the result of computation, it would be nicer to say:
if (someComplicatedExpression ?== 1 : 2 : 3 : 5)
than to say
int temp;
temp = someComplicatedExpression;
if (temp == 1 || temp == 2 || temp == 3 || temp == 5)
particularly if there was no other need for the temp variable in question. A modern compiler could probably recognize the short useful lifetime of 'temp' and optimize it to a register, and could probably recognize the "see if variable is one of certain constants" pattern, but there'd be no harm in allowing a programmer to save the compiler the trouble. The indicated syntax wouldn't compile on any existing compiler, but I don't think it would be any more ambiguous than (a+b >> c+d) whose behavior is defined in the language spec.
As to why nobody's done that, I don't know.
I'm reminded of when I first started to learn programming, in Basic, and at one point I wrote
if X=3 OR 4
I intended this like you are describing, if X is either 3 or 4. The compiler interpreted it as:
if (X=3) OR (4)
That is, if X=3 is true, or if 4 is true. As it defined anything non-zero as true, 4 is true, anything OR TRUE is true, and so the expression was always true. I spent a long time figuring that one out.
I don't claim this adds anything to the discussion. I just thought it might be a mildly amusing anecdote.
As a mathematician, I would say that the colour is primary if and only if it is a member of the set {red, green, blue} of primary colours.
And this is exactly how you could say in Delphi:
isPrimary := Colour in [clRed, clGreen, clBlue]
In fact, I employ this technique very often. Last time was three days ago. Implementing my own scripting language's interpreter, I wrote
const
LOOPS = [pntRepeat, pntDoWhile, pntFor];
and then, at a few lines,
if Nodes[x].Type in LOOPS then
The Philosophical Part of the Question
#supercat, etc. ("As to why nobody's done that, I don't know."):
Probably because the designers of programming languages are mathematicians (or, at least, mathematically inclined). If a mathematician needs to state the equality of two objects, she would say
X = Y,
naturally. But if X can be one of a number of things A, B, C, ..., then she would define a set S = {A, B, C, ...} of these things and write
X ∈ S.
Indeed, it is extremely common that you (mathematicians) write X ∈ S, where S is the set
S = {x ∈ D; P(x)}
of objects in some universe D that has the property P, instead of writing P(X). For instance, instead of saying "x is a positive real number", or "PositiveReal(x)", one would say x ∈ ℝ⁺.
It's because programming languages are influenced by mathematics, logic and set theory in particular. Boolean algebra defines ∧, ∨ operators in a way that they do not work like spoken natural language. Your example would be written as:
Let p(x) be unary relation which holds if and only if x is a primary color
p(x) ⇔ r(x) ∨ g(x) ∨ b(x)
or
p(x) ⇔ (x=red) ∨ (x=green) ∨ (x=blue)
As you see, it's pretty similar to notation that would be used in programming language. As mathematics provide strong theoretic foundations, programming languages are based on mathematics rather than natural language which always leaves a lot of space for interpretation.
EDIT: Above statement could be simplified by using set notation:
p(x) ⇔ x ∈ {red, green, blue}
and indeed, some programming languages, most notably Pascal, included set, so you could type:
type
color = (red, green, blue, yellow, cyan, magenta, black, white);
function is_primary (x : color) : boolean;
begin
is_primary := x in [red, green, blue]
end
But sets as a language feature didn't catch on.
PS. Sorry for my imperfect English.
The latter examples you give are effectively syntactic sugar, they'd have to evaluate to the same code as the longer form as at some point the executed code has to compare your value with each of the conditions in turn.
The array comparison syntax, given in several forms here, closer and I suspect there are other languages which get even closer.
The main problem with making syntax closer to natural language is that the latter is not just ambiguous, it's hideously ambiguous. Even keeping ambiguity to a minimum we still manage to introduce bugs into our apps, can you imagine what it would be like if you programmed in natural english?!
Just to add to language examples
Scheme
(define (isPrimaryColor color)
(cond ((member color '(red blue yellow)) #t)
(else #f)))
(define (someNumberTest x)
(cond ((or (and (>= x 1) (<= x 100)) (and (>= x 10000 (<= x 2000))) #t)
(else #f)))
Two possibilities
Java
boolean isPrimary = Arrays.asList("red", "blue", "yellow").contains(someColor);
Python
a = 1500
if 1 < a < 10 or 1000 < a < 2000:
print "In range"
This can be replicated in Lua with some metatable magic :D
local function operator(func)
return setmetatable({},
{__sub = function(a, _)
return setmetatable({a},
{__sub = function(self, b)
return f(self[1], b)
end}
)
end}
)
end
local smartOr = operator(function(a, b)
for i = 1, #b do
if a == b[i] then
return true
end
end
return false
end)
local isPrimaryColor = someColor -smartOr- {"Red", "Blue", "Either"}
Note: You can change the name of -smartOr- to something like -isEither- to make it even MORE readable.
Languages on computers compare as binary because they are all for a machine that uses binary to represent information. They were designed using similar logic and with broadly similar goals. The English language wasn't designed logically, designed to describe algorithms, and human brains (the hardware it runs on) aren't based on binary. They're tools designed for different tasks.