Lua If statement evaluation - if-statement

If I use:
local a, b ,c
a = 1
b = 1
c = 1
if a == (b or c) then x end
I only ever get a response if b is true c is not evaluated
If I change this to
if (a == b or a == c) then x end
This correctly evaluates either b or c
p.s. I am using this Lua in a Fibaro Home Centre 3 Home automation system.

If you want to check wether a equals b or c this is the correct sytnax:
if a == b or a == c then end
Your parenthesis are ok but not required.
In
local a, b ,c
a = 1
b = 1
c = 1
if a == (b or c) then end
(b or c) resolves to b and thus if a == b then end
The reason for that is called short-circuit evaluation. b is 1 and hence a true value. So the ored expression will be true no matter of c's value. So there is no reason to evaluate c.
From https://www.lua.org/manual/5.4/manual.html#3.4.5
Both and and or use short-circuit evaluation; that is, the second
operand is evaluated only if necessary. Here are some examples:
10 or 20 --> 10
10 or error() --> 10
nil or "a" --> "a"
nil and 10 --> nil
false and error() --> false
false and nil --> false
false or nil --> nil
10 and 20 --> 20
Same here:
if a == b or a == c then end
If a equals b, Lua will not check if a equals c. This is not too obvious but if you would have something like:
local a = 1
function b() print("b") return 1 end
function c() print("c") return 1 end
if a == b() or a == c() then end
Lua would not call c if the return value of b equals a

Related

Ocaml :This expression has type bool but an expression was expected of type unit

I got some issue with my code I don't understand. Why did I get this error: This expression has type bool but an expression was expected of type unit. Here is the code
let well_formed (_dimension : int) (_initial1 : _ list)
(_initial2 : _ list) : bool =
if List.length _initial1 + List.length _initial2 != 4 * _dimension then false
else if List.length _initial1 != List.length _initial2 then false
else
let c = 0 in
for i = 1 to _dimension do
let liste =
List.filter (fun x -> x == i) _initial1
# List.filter (fun x -> x == i) _initial2
in
if List.length liste == 4 then c = c + 1 else c = c
done;
if c == _dimension then true else false
I reformated your code, actually for loop have no impact on your code.
let well_formed dimension initial1 initial2 =
let ll1 = List.length initial1 in
let ll2 = List.length initial2 in
let total_list_length = ll1 + ll2 in
if total_list_length != (4 * dimension) then false else
if ll1 != ll2 then false else
let c = 0 in
(* this code do nothing : what is expected ?
for i = 1 to dimension do
let liste = (List.filter(fun x -> x == i) initial1 )#(List.filter(fun x->x == i) initial2) in
if ( List.length liste ) == 4 then c = c+1 else c = c
done;
*)
if c == dimension then true else false
You need to learn imperative features of ocaml if you want to write code this way.
For example c = c + 1 return false
if you want to increment a variable you need to create a ref variable.
OCaml is not C/Python/Javascript, in particular
x = x + 1
means the same as
x == x + 1
in C or Python, i.e., it is a comparison operator. The == operator is the physical comparison (the same as === in Javascript).
Also, integers in OCaml are immutable, so if you want to have a mutable number you need to wrap it in a reference and use := for assignment, e.g.,
let x = ref 0 in
for i = 0 to 5 do
x := !x + 2
done

In Coq, "if then else" allows non-boolean first argument?

I read in a few tutorials that if a then b else c stands for match a with true => b | false => c end. However the former very strangely does not check the type of a, while the latter of course makes sure that a is a boolean. For instance,
Coq < Check if nil then 1 else 2.
if nil then 1 else 2
: nat
where
?A : [ |- Type]
Coq < Check match nil with true => 1 | false => 2 end.
Toplevel input, characters 33-38:
> Check match nil with true => 1 | false => 2 end.
> ^^^^^
Error: Found a constructor of inductive type bool while
a constructor of list is expected.
Why is if ... then ... else ... allowing its first argument to be anything else than a non-boolean? Is there some overloading going on? (Locate "if". gives no result.)
Let me quote the Coq Reference manual:
For inductive types with exactly two constructors and for pattern-matchings expressions which do not depend on the arguments of the constructors, it is possible to use a if ... then ... else ... notation. More generally, for an inductive type with constructors C1 and C2, we have the following equivalence:
if term [dep_ret_type] then term1 else term2
is equivalent to
match term [dep_ret_type] with
| C1 _ ... _ => term1 (* we cannot bind the arguments *)
| C2 _ ... _ => term2
end
As you can see, the first constructor is treated as true value. Here is an example:
Definition is_empty {A : Type} (xs : list A) : bool :=
if xs then true else false.

Haskell--List appending using Guards

I am working on a simulation for a checkers game currently. I have developed a function called onemove:
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
This function takes a tuple as input and returns a tuple of modified information. I have defined the input variables as follows:
onemove (a,b,c,(d,e))
Where c is a list of chars, ie, captured pieces. I am currently utilizing guards and a where clause to complete the move to be made from 'd' to 'e'. How do I append an element to the list b within the where clause, if even possible? My sample code is as follows:
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
onemove (a,b,c,(d,e))
| e <= 0 =(a-30,b,c)
| (posFrom == 'r') && (posTo == '-') && ( leftOrRight == 9) = (a-15,b,removeWRightMan)
| otherwise = (10000,b,c)
where posFrom = getPos d c
rightWGuy = d+4
b ++ rightWGuy
removeWRightMan = setPos rightWGuy sFPosTo '-'
The value rightWGuy is however an Int and I am attempting to pass it to a [char]..Does this need to be converted to a char before attepting to append to the list b? Thanks
Well to just convert rightWGuy to a [Char] you could do:
import Data.Char (intToDigit)
-- some other things
b ++ [(intToDigit rightWGuy)]
Note that intToDigit only works for input in range [0..15]!
Alternatively, to simplify you can also just use show. Another advantage of show is that it supports any number, not only 0 to 15.
b ++ (show rightWGuy)
With the clarification of your comment, you probably want to so this:
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
onemove (a,b,c,(d,e))
| e <= 0 =(a-30,b,c)
| (posFrom == 'r') && (posTo == '-') && ( leftOrRight == 9) = (a-15,x,removeWRightMan) -- instead of b use x now
| otherwise = (10000,b,c)
where
posFrom = getPos d c
rightWGuy = d+4
x = b ++ (show rightWGuy) -- x is now b ++ rightWGuy
removeWRightMan = setPos rightWGuy sFPosTo '-'
Because Haskell has no side effects, just doing b ++ [(intToDigit rightWGuy)] will not change b, it will yield a new list which is the result of the concatenation. This result we now store in x, which we will use in our new tuple as you wish to do.

Erlang: How to "Do Nothing" in true branch of if statement

I have this if statement:
if
A /= B -> ok;
true ->
end.
I want it to do nothing when A == B.
Erlang does not have the notion of nothing like void or unit. I would suggest returning another atom like not_ok (or even void or unit.)
The best answer is don't use if, just use case.
case A of
B -> ok;
C -> throw({error,a_doesnt_equal_b_or_whatever_you_want_to_do_now})
end
typically ok or undefined or noop are returned as atoms which mean essentially, nothing.
As said, any code will return something.
If you want to do something only in one case, then you can write this:
ok =if
A /= B -> do_something(A,B); % note that in this case do_something must return ok
true -> ok
end.
if you want to get new values for A, B you can write this
{NewA,NewB} = if
A /= B -> modify(A,B); % in this case modify returns a tuple of the form {NewA,NewB}
true -> {A,B} % keep A and B unchanged
end.
% in the following code use only {NewA,NewB}
or in a more "erlang way"
%in your code
...
ok = do_something_if_different(A,B),
{NewA,NewB} = modify_if_different(A,B),
...
% and the definition of functions
do_something_if_different(_A,_A) -> ok;
do_something_if_different(A,B) ->
% your action
ok.
modify_if_different(A,A) -> {A,A};
modify_if_different(A,B) ->
% insert some code
{NewA,NewB}.
last if you expect that it crashes if A == B
%in your code
...
ok = do_something_if_different_else_crash(A,B),
...
% and the definition of functions
do_something_if_different_else_crash(A,B) when A =/= B ->
% your action
ok.

C++ - how does the || operator work?

I have seen this syntax in a program but I am not sure what happens at the return part. What does the ||(or) mean? Does this mean that the method returns true when at least one of a and b is true and returns false when both of them are false?
bool A::truthValue() {
bool a = true;
bool b = true;
if(........)
a= false;
if(........)
b=false
return (a || b);
}
It will return true if either b or a is true. This means that the result is (see table):
a | b | result
t | t | t
f | t | t
t | f | t
f | f | f
Actually in your specific case, false will be returned only if both if statements become true.
EDIT So - your suggestion is correct.
It means return true if a or b is true.
Does this mean that the method returns true when at leas one of a and b is true and returns false when both of them are false?
It means exactly that.
More precisely: The || operator will first evaluade the expression on the left side. If it is true, the expression on the right side is ignored and the whole || expression evaluades to true. If the left expression is false, the right expression is evaluated; if it is true the whole || expression evaluades true, otherwise false.
This behavior is well defined and not trivial. This logic exlusion applies to all logic operators in C++, which allows things like:
if (p && *p != '\0')
Which would not be allowed, if this rule would not exist.