Reputation: 75
I hope everyone is safe.
I am learning Haskell and came upon the fact that a function in Haskell has no side-effect. I just wondered in imperative languages are boolean expression considered to be expression with no side-effects since they only return true or false (their main effect)
Thanks!
Upvotes: 3
Views: 309
Reputation: 477318
In an imperative language, expressions can normally have side-effects. For example in Python:
def f(x):
print(x)
return True
if f(2) or f(4):
print(3)
Here it thus prints to the standard output channel, which is a side-effect. It can also do file I/O, insert records in a database, perform network I/O, insert elements in a list, create a process, and other forms of side effects.
Regardless the type of the expression, it can normally have side effects. In safe Haskell, one can normally not perform any I/O, unless you make use of an IO
, so then it is IO Bool
, not Bool
. Furthermore all variables are immutable, hence you can not add elements to a list, you can construct a new list, but then there are no effects for readers of the "old" list.
If you of course specify that they only return True
or False
, and thus do not have any side-effects, then a boolean expression has no side effects, since not
, and
, or
, etc. normally have no side-effects either. But the problem is that you can not say if a function has side-effects in Python (and other imperative languages) based on the return type.
The idea that functions have no side-effects enables a lot of optimizations the compiler can do. For example in Haskell everything is evaluated lazily, that means that unless you need to know the value of something, it remains unevaluated. This is possible since the order of evaluating functions with no side-effects is not important. If a function can not alter a list that is accessible by another function, then it thus can not have impact on the result of that list.
It furthermore makes it easier to run things in parallel, since again, a function with no side-effects, can not have impact on the results of another function, hence the two functions can be evaluated by different cores.
But perhaps the most useful consequence is that it makes programs very modular, and less error-prone. A lot of bugs result from the fact that a function makes changes to an object, database, etc. and that the function later in the program did not anticipate on these changes. For example if a function removes a record from the database, then the next function might work under the assumption that this record is still there.
Upvotes: 6