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.logexecutes some effect and returnsvoidConsole.logonly 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); // voidAgain, 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(); // voidEffect.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