Yacoub Massad (5) [Avatar] Offline
#1
Hello.

I am reading the MEAP and I am in chapter 2, section 2.3.1, page 45.

The book asks "What kind of side effect are we facing here?", referring to the usage of DateTime.UtcNow.

The way I understand side effects is that they change something in the system. DateTime.UtcNow is a query and it does not change anything.

Am I missing something? Or is this simply a mistake?

Thanks.
Stive (9) [Avatar] Offline
#2
Wikipedia : "a function or expression is said to have a side effect if it modifies some state outside its scope or has an observable interaction with its calling functions or the outside world."

When a function calls DateTime.UtcNow, it interacts with the outside world, requesting an external system (the clock) to return its internal state (the current time).
If the result of such a function depends on the clock, then that result is unpredictable : the function is impure.
Yacoub Massad (5) [Avatar] Offline
#3
I see, thanks.

Looking back in section 2.1.1, the author included in the definition of a side effect any IO operation (including reading).

So the FP community considers IO reading to be a side effect. I am not sure if this is a good idea. I think it is very important to distinguish between "side effects" that don't change any thing in the system/environment and "side effects" that do change something in the system/environment.
Yacoub Massad (5) [Avatar] Offline
#4
In section 4.2, the author is speaking about using ForEach for side effects.

He is advising us to use Map for data transformations and ForEach for side effects.

The way he uses "side effects" here does not make sense for IO reading. Here the meaning of side effects is more like: things that return nothing but instead change the state of the system/environment/etc..
Stive (9) [Avatar] Offline
#5
I think you should not focus too much on the term "side effect".
What is really important is : is the function pure or not ?
Enrico Buonanno (87) [Avatar] Offline
#6
Hi Yacoub,

it's true what you say, that not everyone agrees on the definition of "side effect".

In FP, anything that introduces indeterminism is considered a side effect, including reading from IO and even reading from mutable state. If you embrace this wider definition of side effect, then absence of side effects and purity are equivalent.

On the other hand, it's true that when programmers conversationally refer to a "side effect" they tend to mean writing.

As for section 4.2: `ForEach` takes an `Action`, which returns no data, so you wouldn't use it to model reading from IO to begin with. So, yes, in this case, I'm implicitly only referring to "write" side effects.
Enrico Buonanno (87) [Avatar] Offline
#7
Yacoub Massad wrote:So the FP community considers IO reading to be a side effect. I am not sure if this is a good idea. I think it is very important to distinguish between "side effects" that don't change any thing in the system/environment and "side effects" that do change something in the system/environment.


The thing is, your notion of side effects "that don't change anything in the system/environment" is naive. Does reading from the DB not change the system (does it not open a connection? does it not log diagnostic entries in the DB?). Does reading from a remote API not change the system? (What if you're charged money for each request? Or for each 1000 requests? What if too frequent requests cause your account to be blocked? What if the API client writes to a DB that influences your system?)

In addition, there's the question of indeterminacy: read from the DB, and you may get a different result every time.

For these 2 reasons, a wide interpretation of side effects including reads is preferable.
Yacoub Massad (5) [Avatar] Offline
#8
Sorry for this late comment, but I never received a notification about your comments.

I still think that it is important to distinguish between "read side effects" and "write side effects".

It is all about intention.

It is true that reading data from a database might include some implicit writes or other effects such as opening a connection and maybe charging money or writing to a log. But a similar thing can be said about reading from memory or using the CPU to do some mathematical calculations. In the cloud for example, if you use the CPU, you are charged money for that.
Also, when you do read from the memory, some low-level things change inside the machine (e.g. CPU registers? Memory cache?).

I am not suggesting that we should treat memory reads and CPU consumption the same way we treat IO reads. I am only stating that it is important to distinguish between reads and writes when we talk about IO.

Again, it is all about code intention. When you write code to read from the disk, as far as you are concerned, this does not change anything (although a lot could be "changed" at a lower level). When you write code to write to disk, it is a different story. Here you intend to change some state in the system.

Of course, pure functions means no I/O at all. But I think IO reads should be given a label that is different than IO writes.

My main issue is the "effect" part of "side effect".

This is a terminology issue and I just wanted to give my input on it.