Erlang if else statement - functional-programming

Im trying to do a method where it checks the value of two atoms, if they are equivalent to each other it gonna say it's false and the other way around, if they aren't equivalent it's gonna be true.
my code looks like this:
b_not(X, Y) ->
if
X=:=Y ->
false;
else
true;
end.
Here the name of my method is "b_not" which stands for boolean_not. and I check with the if-statement if X is exactly equal to Y it gonna say false. Ok that part alone I could do.
But my problem comes to when I try to make the else-statement.
I don't seem to get this part, I tried to search around on the internet, but I don't seem to get it.
So if you could tell me how the if-else-statement works in Erlang, I would be pleased!
Thanks Alexein!

I'm relatively new to Erlang, but the language isn't designed to work in the way you describe. There is an if construct, but I don't believe it's used often.
Instead, what you describe can be achieved like this using pattern matching:
b_not(_X, _X) -> false;
b_not(_, _) -> true.
The underscore pattern match indicates a wildcard; a pattern match which is preceded by an underscore means that you do not intend to use the value in the function, but you do care about the matching itself.
So the first pattern match means "I don't intend to use _X for anything, but both values must be the same."
The second pattern match means "These are throwaway values and can be anything at all."
Many functions are defined with multiple argument patterns, and Erlang decides for you which of the patterns matches the invocation.
In this case, if an identical value is passed twice, whether that be an integer, atom, list, or any other type, the first pattern will be matched and false will be returned. Otherwise, the second pattern is matched.
This only works because the patterns are defined in this order; if they were reversed, any arguments would result in true.
Illustrations:
16> foo:b_not(3, 3).
false
17> foo:b_not(3, 4).
true
19> foo:b_not(3, 3.0).
true
20> foo:b_not(match, match).
false
21> foo:b_not(match, nomatch).
true
22> foo:b_not([1, 2], [1, 2]).
false
23> foo:b_not([1, 2], [1, 2, 3]).
true

That is what the =/= operator do!
b_not(X, Y) -> X =/= Y.
I can understand your confusion about if statements. You should really read about if and guards in the manual because if do not work as in many other languages. This is one way of achieving it in Erlang (but "if true then true" is kind of an anti-pattern so don't do exactly this):
if
X =/= Y -> true;
X =:= Y -> false
end
Note that when one of the guards (to the left of the arrow) evaluates to the true atom the if statement will evaluate to the expression following that arrow. There is no else clause but you can invent one yourself by putting true before the arrow:
if
X =/= Y -> true;
true -> false
end
This is not very intuitive, especially not for people from other language backgrounds, and I suppose that is one reason pattern matching are often preferred over if expressions.
For completeness, read up on the case expression as well. It is meant for doing pattern matching inside the body of a function:
case X of
Y -> false; % X equals Y
_ -> true % Everything else, i.e., X is not Y
end

Related

Erlang Recursive end loop

I just started learning Erlang and since I found out there is no for loop I tried recreating one with recursion:
display(Rooms, In) ->
Room = array:get(In, Rooms)
io:format("~w", [Room]),
if
In < 59 -> display(Rooms, In + 1);
true -> true
end.
With this code i need to display the content (false or true) of each array in Rooms till the number 59 is reached. However this creates a weird code which displays all of Rooms contents about 60 times (?). When I drop the if statement and only put in the recursive code it is working except for a exception error: Bad Argument.
So basically my question is how do I put a proper end to my "for loop".
Thanks in advance!
Hmm, this code is rewritten and not pasted. It is missing colon after Room = array:get(In, Rooms). The Bad argument error is probably this:
exception error: bad argument
in function array:get/2 (array.erl, line 633)
in call from your_module_name:display/2
This means, that you called array:get/2 with bad arguments: either Rooms is not an array or you used index out of range. The second one is more likely the cause. You are checking if:
In < 59
and then calling display again, so it will get to 58, evaluate to true and call:
display(Rooms, 59)
which is too much.
There is also couple of other things:
In io:format/2 it is usually better to use ~p instead of ~w. It does exactly the same, but with pretty printing, so it is easier to read.
In Erlang if is unnatural, because it evaluates guards and one of them has to match or you get error... It is just really weird.
case is much more readable:
case In < 59 of
false -> do_something();
true -> ok
end
In case you usually write something, that always matches:
case Something of
{One, Two} -> do_stuff(One, Two);
[Head, RestOfList] -> do_other_stuff(Head, RestOfList);
_ -> none_of_the_previous_matched()
end
The underscore is really useful in pattern matching.
In functional languages you should never worry about details like indexes! Array module has map function, which takes function and array as arguments and calls the given function on each array element.
So you can write your code this way:
display(Rooms) ->
DisplayRoom = fun(Index, Room) -> io:format("~p ~p~n", [Index, Room]) end,
array:map(DisplayRoom, Rooms).
This isn't perfect though, because apart from calling the io:format/2 and displaying the contents, it will also construct new array. io:format returns atom ok after completion, so you will get array of 58 ok atoms. There is also array:foldl/3, which doesn't have that problem.
If you don't have to have random access, it would be best to simply use lists.
Rooms = lists:duplicate(58, false),
DisplayRoom = fun(Room) -> io:format("~p~n", [Room]) end,
lists:foreach(DisplayRoom, Rooms)
If you are not comfortable with higher order functions. Lists allow you to easily write recursive algorithms with function clauses:
display([]) -> % always start with base case, where you don't need recursion
ok; % you have to return something
display([Room | RestRooms]) -> % pattern match on list splitting it to first element and tail
io:format("~p~n", [Room]), % do something with first element
display(RestRooms). % recursive call on rest (RestRooms is quite funny name :D)
To summarize - don't write forloops in Erlang :)
This is a general misunderstanding of recursive loop definitions. What you are trying to check for is called the "base condition" or "base case". This is easiest to deal with by matching:
display(0, _) ->
ok;
display(In, Rooms) ->
Room = array:get(In, Rooms)
io:format("~w~n", [Room]),
display(In - 1, Rooms).
This is, however, rather unidiomatic. Instead of using a hand-made recursive function, something like a fold or map is more common.
Going a step beyond that, though, most folks would probably have chosen to represent the rooms as a set or list, and iterated over it using list operations. When hand-written the "base case" would be an empty list instead of a 0:
display([]) ->
ok;
display([Room | Rooms]) ->
io:format("~w~n", [Room]),
display(Rooms).
Which would have been avoided in favor, once again, of a list operation like foreach:
display(Rooms) ->
lists:foreach(fun(Room) -> io:format("~w~n", [Room]) end, Rooms).
Some folks really dislike reading lambdas in-line this way. (In this case I find it readable, but the larger they get the more likely the are to become genuinely distracting.) An alternative representation of the exact same function:
display(Rooms) ->
Display = fun(Room) -> io:format("~w~n", [Room]) end,
lists:foreach(Display, Rooms).
Which might itself be passed up in favor of using a list comprehension as a shorthand for iteration:
_ = [io:format("~w~n", [Room]) | Room <- Rooms].
When only trying to get a side effect, though, I really think that lists:foreach/2 is the best choice for semantic reasons.
I think part of the difficulty you are experiencing is that you have chosen to use a rather unusual structure as your base data for your first Erlang program that does anything (arrays are not used very often, and are not very idiomatic in functional languages). Try working with lists a bit first -- its not scary -- and some of the idioms and other code examples and general discussions about list processing and functional programming will make more sense.
Wait! There's more...
I didn't deal with the case where you have an irregular room layout. The assumption was always that everything was laid out in a nice even grid -- which is never the case when you get into the really interesting stuff (either because the map is irregular or because the topology is interesting).
The main difference here is that instead of simply carrying a list of [Room] where each Room value is a single value representing the Room's state, you would wrap the state value of the room in a tuple which also contained some extra data about that state such as its location or coordinates, name, etc. (You know, "metadata" -- which is such an overloaded, buzz-laden term today that I hate saying it.)
Let's say we need to maintain coordinates in a three-dimensional space in which the rooms reside, and that each room has a list of occupants. In the case of the array we would have divided the array by the dimensions of the layout. A 10*10*10 space would have an array index from 0 to 999, and each location would be found by an operation similar to
locate({X, Y, Z}) -> (1 * X) + (10 * Y) + (100 * Z).
and the value of each Room would be [Occupant1, occupant2, ...].
It would be a real annoyance to define such an array and then mark arbitrarily large regions of it as "unusable" to give the impression of irregular layout, and then work around that trying to simulate a 3D universe.
Instead we could use a list (or something like a list) to represent the set of rooms, but the Room value would now be a tuple: Room = {{X, Y, Z}, [Occupants]}. You may have an additional element (or ten!), like the "name" of the room or some other status information or whatever, but the coordinates are the most certain real identity you're likely to get. To get the room status you would do the same as before, but mark what element you are looking at:
display(Rooms) ->
Display =
fun({ID, Occupants}) ->
io:format("ID ~p: Occupants ~p~n", [ID, Occupants])
end,
lists:foreach(Display, Rooms).
To do anything more interesting than printing sequentially, you could replace the internals of Display with a function that uses the coordinates to plot the room on a chart, check for empty or full lists of Occupants (use pattern matching, don't do it procedurally!), or whatever else you might dream up.

Learning functional programming - having trouble conceptualizing "no if statements" [duplicate]

This question already has answers here:
What's a functional replacement for if-then statements?
(7 answers)
Closed 9 years ago.
I was discussing programming with a friend, who is an advocate for functional programming. He mentioned that you don't need to use if statements, but I can't seem to conceptualize how you would implement
if (something):
do this;
else:
do something_else;
In a functional paradigm?
Edit: my friend specifically mentioned that there are cases where you wouldn't need to use an if expression, even though you can. For example:
if x is odd:
x + 1
else:
x / 2
Is there a way to implement the above without using any if statements or conditionals?
Without more context it's hard to know exactly what your friend meant, but two things come to mind that he could have reasonably meant:
In functional languages if conditionals are expressions, not statements, so you'd be using if expressions and not if statements. This difference means that you write things like:
let x =
if condition
then value1
else value2
Instead of:
let x be a mutable variable
if condition
then x = value1
else x = value2
So this allows you to write in functional style without mutating variables.
The other thing he could have meant is that many functional languages offer constructs like pattern matching or guards that you can use instead of if statements. Pattern matching allows you to inspect the structure of a value and take it apart at the same time. As an example you can write this:
match my_list with
| x :: xs -> x + sum xs
| [] -> 0
Instead of this:
if my_list is empty
then
let x be the first element of my_list
let xs be the list containing the remaining elements of my_list
x + sum xs
Using pattern matching is preferable because it avoids calling functions on a value whose structure does not support it. In the example above, a function that returns the first element of a list would presumably cause an error when called on an empty list (which might happen if we mess up the if condition). But if we use pattern matching to get at the first element this can't happen because the syntax of the matching construct ensures that we only get x and xs if my_list is really not empty.
Pattern guards allow you to add arbitrary conditions to pattern matching:
match f(x) with
| 0 -> "f(x) was zero"
| 1 -> "f(x) was one"
| x when x > 1 -> "f(x) was greater than one"
| _ -> "f(x) was negative"
This can be cleaner if you're pattern matching anyway, but that hardly means you shouldn't use if expressions in functional languages. If you don't have a situation where you want pattern match on a value, introducing a pattern match just so that you can use a guard makes little sense over using an if statement.
The part that should confuse you isn't the if, it's the "do".
In functional programming, you don't "do" anything.
You just define the result to be some function of the input.
The function may of course have conditionals (like cond ? a : b in languages like C#, Java, C++, etc.), but a and b are expressions that evaluate to some common type; they are not statements -- so the result is either a or b, depending on cond.

Conditional function in APL

Is there a symbol or well-known idiom for the conditional function, in any of the APL dialects?
I'm sure I'm missing something, because it's such a basic language element. In other languages it's called conditional operator, but I will avoid that term here, because an APL operator is something else entirely.
For example C and friends have x ? T : F
LISPs have (if x T F)
Python has T if x else F
and so on.
I know modern APLs have :If and friends, but they are imperative statements to control program flow: they don't return a value, cannot be used inside an expression and certainly cannot be applied to arrays of booleans. They have a different purpose altogether, which is just fine by me.
The only decent expression I could come up with to do a functional selection is (F T)[⎕IO+x], which doesn't look particularly shorthand or readable to me, although it gets the job done, even on arrays:
('no' 'yes')[⎕IO+(⍳5)∘.>(⍳5)]
no no no no no
yes no no no no
yes yes no no no
yes yes yes no no
yes yes yes yes no
I tried to come up with a similar expression using squad ⌷, but failed miserably on arrays of booleans. Even if I could, it would still have to embed ⎕IO or an hardcoded 1, which is even worse as far as readability is concerned.
Before I go ahead and define my own if and use it on every program I will ever write, is there any canon on this? Am I missing an obvious function or operator?
(Are there any APL programmers on SO? :-)
The trouble with these:
(f t)[x]
x⌷f t
x⊃f t
is that both t and f get evaluated.
If you want to short-circuit the thing, you can use guards:
{x:t ⋄ f}
This is equivalent to
if (x) {
return t;
}
f;
in a C-like language.
Yes, there are APL programmers on SO (but not many!).
I think the answer is that there is no standard on this.
For a scalar solution, I use "pick":
x⊃f t
While for a Boolean array I use indexing as you do above:
f t[x]
I always use index origin zero, so there is no need to add 1, and the parens are not needed.
If these are not simple enough, I think you have to cover them with a function named "if". That will also let you put the true and false in the perhaps more natural ordering of t f.
In Dyalog APL you can use:
'value if true' (⊣⍣condition) 'value if false'
The idea is applying ⊣ (left tack – which always returns its left argument, while discarding the right argument) either 0 (for false) or 1 (for true) times – to the right argument. So, if it is applied 0 time (i.e. not at all), the right argument is returned unmodified, but if it is applied (once), then the left argument is applied. E.g.:
a b←3 5
Conditional←⊣⍣(a=b)
'match' Conditional 'different'
different
a b←4 4
Conditional←⊣⍣(a=b)
'match' Conditional 'different'
match
or
Cond←{⍺(⊣⍣⍺⍺)⍵}
bool←a=b
'match'(bool Cond)'different'
match
An old, old idiom which did something like C's ternary operator ? : and returned a result was the following:
r←⍎(¯3 3)[x=42]↑'6×8 ⋄ 6×7'
Note that this is written for origin 0 and the parens around the -3 3 are there for clarity.
x=42 evaluates to zero or one, depending on this answer we choose -3 or 3, and thus select and execute either the first 3 elements ("6x8") or last 3 elements ("6x7") of the string. The diamond ⋄ is just there for decoration.
Needless to say, one would probably not code this way if one had :if :else avaiable, though the control structure form would not return a result.
This is a common question, I think the reason there is no standard answer to it is that for the things you do with APL, there is actually less need for it than other languages.
That said, it is sometimes needed, and the way I implement an IFELSE operator in GNU APL is using this function:
∇Z ← arg (truefn IFELSE falsefn) condition ;v
v←⍬
→(0=⎕NC 'arg')/noarg
v←arg
noarg:
→condition/istrue
Z←falsefn v
→end
istrue:
Z←truefn v
end:
∇
The function can be called like this:
3 {'expression is true' ⍵} IFELSE {'was false' ⍵} 0
was false 3
This particular implementation passes in the left-hand argument as ⍵ to the clause, because that can be handy sometimes. Without a left-hand argument it passes in ⍬.
The APL expression:
(1+x=0)⌷y z
should be the C language equivalent for
x?y:z
And all the others
(1+x>0)⌷y z
for
x<=0?y:z
Etc. In general if a b c are expressions of respective languages the APL expression:
(1+~a)⌷b c
It should be equivalent to the C language:
a?b:c

How can I bubble an "impossible" value up via a recursive algorithm?

I have a recursive algorithm with special cases, for example a path algorithm where I want to add 1 to the distance if the path is good, but return -1 if it hits a dead-end. This is problematic when solving maximization problems with a bunch of recursive calls.
Is there a better way to code the following:
def rec(n):
if n == 1:
return -1
if n == 0:
return 1
val = rec(n - 2)
if val == -1:
return -1
else:
return val + 1
Therefore, rec(4) = 2, rec(3) = -1
In Python, not really. You could make it clearer in Python by returning None rather than -1; this has the advantage that erroneously adding to the invalid value will throw an exception.
A language that has a more rigorous type system and a good concept of 'maybe' or optional values makes it a snap. Say, Haskell:
rec 1 = Nothing
rec 0 = Just 1
rec n = map ((+) 1) $ rec (n - 2)
The map invocation means that it will add whatever is in the box if it is Just x, and return the invalid value (Nothing) unchanged. Of course, you can design your own more sophisticated type that allows for multiple error conditions or whatever and still obtain similarly simple results. This is pretty much just as easy in OCaml, F#, Standard ML, and Scala.
You can simulate this approach with None in Python by defining a helper function:
def mapMaybe(obj, f):
if obj is None:
return None
else:
return f(obj)
Then you can do:
return mapMaybe(val, lambda x: x + 1)
But I don't know that I would really recommend doing that.
Simulating a trick from Scala's book, it would also be possible to wrap all of this up in generator comprehensions (untested):
def maybe(x):
if x is not None:
yield x
def firstMaybe(it):
try:
return it.next()
except StopIteration:
return None
Then:
return firstMaybe(x + 1 for x in maybe(val))
But that's really non-standard, non-idiomatic Python.
A useful technique is to select a "no solution available" value such that processing it as though it represented a solution would still yield a "no solution available" value. If low numbers represent optimal solutions, for example, one could choose a value which is larger than any valid solution which would be of interest. If one is using integer types, one would have to make sure the "no solution available" value was small enough that operating on it as though it were a valid solution would not cause numerical overflows [e.g. if recursive calls always assume that the cost of a solution from some position will be one greater than the cost of a solution generated by the recursive call, then using values greater than 999,999,999 to represent "no solution avaialble" should work; if code might regard the cost of the solution as being the sum of two other solutions, however, it may be necessary to choose a smaller value]. Alternatively, one might benefit from using floating-point types since a value of "positive infinity" will compare greater than any other value, and adding any positive or finite amount to it won't change that.

Predicates returning. Prolog

So I have the predicate which returns true several time.
% true returns several times and i need to press ';'
?- get_all_transformed_moves.
true ;
true ;
true.
Is the swi prolog have some method which can help me to run this predicate without typing';'?
% Wished version
?- get_all_transformed_moves.
true.
Consider the following:
likes(prolog).
likes(haskell).
likes(erlang).
likes_something:-
likes(_Something).
if now you ask:
?- likes_something.
you will get
true ;
true ;
true.
this happens because prolog finds three ways to satisfy the likes_something/0 predicate (with prolog, haskell and erlang) so it answers true for three times.
this isn't exactly a problem; at any time you can press and prolog will stop trying to find answers (this is quite handy when there are a lot of results).
the same thing happens to your predicate: there are three solutions and by pressing ; you force prolog to find them all. as Rocha suggested you could use findall/3. For example, you could write:
likes_something:-
findall(X, likes(X), _).
and this will return just one yes
however, it doesn't offer more information than the previous version; instead it hides the fact that there are 3 solutions and wastes time trying to find more while the answer wont change.
For that reason I think that you should use findall/3 if you actually want to see the results:
likes_all(L):-
findall(X,likes(X),L).
of course, the decision of whether you need to see the results or not is up to you (or rather to the problem you are trying to solve :p)
another option is to use a cut: !/0
for example:
likes_something:-
likes(_Something),
!.
this will stop prolog from searching for more solutions and you will get just one true.
note however that cuts can be tricky.
All in all:
if you want prolog to search for all the answers (if you decide to put them in a list or you have side-effects in your predicates or if you just want it): use findall/3
if you don't want to have the option to search for more answers: use a cut (!/0)
else just press enter instead of ;
You can use the findall/3 predicate:
findall(Object,Goal,List).
produces a list List of all the objects Object that satisfy the goal Goal. Often Object is simply a variable, in which case the query can be read as: Give me a list containing all the instantiations of Object which satisfy Goal.
I suppose that is what you want.
If you want the predicate to succeed at most once, then you can use once/1 provided with SWI.
In your example:
?- once(get_all_transformed_moves).
true.

Resources