Let's come back to index.ts
:
import { Console, Effect } from "effect";
const main = Console.log("Hello world");
Effect.runSync(main);
This is the "Hello World" of effect, equivalent to console.log
.
We can already notice the first major difference with effect programs: in effect defining the app (main
) and executing it (Effect.runSync
) are two separate actions.
We explicitly execute, meaning that effects don't run eagerly like console.log
does!
/// 1️⃣ Define the `main` app
const main = Console.log("Hello world");
/// 2️⃣ Execute app
Effect.runSync(main);
Why is that?
An Effect
is a description of a series of operations:
console.log
executes some effect and returnsvoid
Console.log
only describes what will happen without executing any effect
/// 👇 `native` is `void`, the effect has already been executed!
/// This operation already "did" something!
const native: void = console.log("Hello world");
/// 👇 `effect` is `Effect<void>`, it describe something that when executed returns `void`
/// This only describes what should happen, it didn't do anything yet
const effect: Effect<void> = Console.log("Hello world");
Effect
alone does not execute any logic. Instead, you need to explicitly call a run*
method (in this example runSync
).
This is similar to storing a function instead of executing it:
/// 1️⃣ Define the `main` app
const main = () => console.log("Hello World");
/// 2️⃣ Execute app (explicitly)
main();
Functional effects are immutable data structures that merely describe sequences of operations.
They have to be explicitly run to execute real effects.
How Console.log works
Console.log
is a function that returns Effect<void>
.
In practice this means that Console.log
, when executed, returns void
:
// 👇 Definition
const main: Effect<void> = Console.log("Hello world");
// 👇 Execution
Effect.runSync(main); // void
Again, this is similar to a function that when executed prints in the console:
type Program<T> = () => T;
// 👇 Definition
const main: Program<void> = () => console.log("Hello World");
// 👇 Execution
main(); // void
Effect.runSync
takes as input an Effect
and runs it synchronously.
Result: run a sync program that prints the string "Hello World"
and returns void
:
- "run a sync program...":
Effect.runSync
- "...that prints the string
"Hello World"
...":Console.log("Hello World")
- "...and returns
void
":Effect<void>
import { Console, Effect } from "effect";
const main = Console.log("Hello world");
Effect.runSync(main);
> effect-getting-started-course@1.0.0 dev
> tsx src/index.ts
Hello world