Effects

Effects declare the side effects a function may have. This is unique to Calor - traditional languages leave side effects implicit.


Why Declare Effects?

In traditional languages, you must read the entire implementation to know if a function:

  • Writes to console
  • Reads files
  • Makes network calls
  • Modifies a database

Calor requires explicit effect declarations:

Plain Text
§F{f001:SaveUser:pub}
  §I{User:user}
  §O{bool}
  §E{db:rw,net:rw}        // Declares: database and network operations
  // ...
§/F{f001}

Now an agent knows immediately what side effects to expect.


Effect Syntax

Plain Text
§E{code1,code2,...}
§E{}                      // No effects (pure function)

Place the effect declaration after the output type:

Plain Text
§F{id:name:vis}
  §I{...}
  §O{...}
  §E{effects}             // Here
  §Q ...
  §S ...
  // body
§/F{id}

Effect Codes

CodeEffectDescriptionC# Examples
cwConsole writeOutput to consoleConsole.WriteLine()
crConsole readInput from consoleConsole.ReadLine()
fs:rFilesystem readRead from filesystemFile.ReadAllText()
fs:wFilesystem writeWrite to filesystemFile.WriteAllText()
fs:rwFilesystem read/writeRead and write filesystemFile.Copy()
net:rNetwork readHTTP GET, etc.HttpClient.GetStringAsync()
net:wNetwork writeHTTP POST, etc.HttpClient.PostAsync()
net:rwNetwork read/writeHTTP operationsHttpClient.SendAsync()
db:rDatabase readDatabase queriesSELECT queries
db:wDatabase writeDatabase mutationsINSERT/UPDATE/DELETE
db:rwDatabase read/writeDatabase operationsORM calls

Examples

Pure Function (No Effects)

Plain Text
§F{f001:Add:pub}
  §I{i32:a}
  §I{i32:b}
  §O{i32}
  // No §E means pure - no side effects
  §R (+ a b)
§/F{f001}

Or explicitly:

Plain Text
§F{f001:Add:pub}
  §I{i32:a}
  §I{i32:b}
  §O{i32}
  §E{}                    // Explicitly no effects
  §R (+ a b)
§/F{f001}

Console Output

Plain Text
§F{f001:Greet:pub}
  §I{str:name}
  §O{void}
  §E{cw}                  // Console write
  §P name
§/F{f001}

File Operations

Plain Text
§F{f001:CopyFile:pub}
  §I{str:source}
  §I{str:dest}
  §O{bool}
  §E{fs:rw}               // Filesystem read and write
  // ...
§/F{f001}

Network Call

Plain Text
§F{f001:FetchData:pub}
  §I{str:url}
  §O{str!str}
  §E{net:rw}              // Network operations
  // ...
§/F{f001}

Database with Logging

Plain Text
§F{f001:CreateUser:pub}
  §I{User:user}
  §O{i32}
  §E{db:rw,cw}            // Database and console (for logging)
  // ...
§/F{f001}

Multiple Effects

Plain Text
§F{f001:ProcessOrder:pub}
  §I{Order:order}
  §O{bool}
  §E{db:rw,net:rw,fs:w,cw} // Database, network, filesystem write, console write
  // ...
§/F{f001}

Effect Patterns

Read-Only vs Read-Write

Plain Text
// Read-only file operation
§F{f001:LoadConfig:pub}
  §I{str:path}
  §O{Config}
  §E{fs:r}                // Only filesystem read
  // ...
§/F{f001}

// Read-write file operation
§F{f002:UpdateConfig:pub}
  §I{str:path}
  §I{Config:config}
  §O{void}
  §E{fs:rw}               // Filesystem read and write
  // ...
§/F{f002}

Interactive Console

Plain Text
§F{f001:Prompt:pub}
  §I{str:question}
  §O{str}
  §E{cw,cr}               // Console write and read
  §P question
  §R §C{Console.ReadLine} §/C
§/F{f001}

Benefits for Agents

1. Filtering by Effect

"Find all functions that access the database":

Plain Text
// Agent searches for §E{..db..}

2. Refactoring Safety

"This function should be pure, but it has effects":

Plain Text
§F{f001:Calculate:pub}
  §O{i32}
  §E{cw}                  // Wait, why is Calculate logging?

3. Testing Strategy

  • Functions with no effects: Unit test directly
  • Functions with cw/cr: Mock console
  • Functions with fs:r/fs:w/fs:rw: Mock filesystem
  • Functions with net:r/net:w/net:rw: Mock HTTP
  • Functions with db:r/db:w/db:rw: Mock database

4. Composition Analysis

Plain Text
// If f1 calls f2, f1's effects must include f2's effects
§F{f001:ProcessAndSave:pub}
  §E{db:rw,cw}            // Must include f002's effects
  §C{f002:Process} ... §/C
§/F{f001}

§F{f002:Process:pri}
  §E{cw}                  // Has console write effect
  // ...
§/F{f002}

Effect Checking

The compiler warns if:

  1. Missing effect: Function has side effect but doesn't declare it
  2. Unused effect: Function declares effect but doesn't use it
  3. Propagation: Caller doesn't include callee's effects

Next