Complete Broadcast Feature Rules
Core Concept:
One broadcasted main() per package that any file in the package can execute.
Rule 1: Broadcast Declaration
Only one file per package can declare a broadcast.
// File: app.cod (the broadcaster)
unit my.app (main: BusinessLogic) // ✅ Only one per package
BusinessLogic {
share main() {
outln("Running business logic...")
}
}
Rule 2: Execution Priority
When executing any .cod file:
Priority Order:
- File's own main() (if exists) → runs immediately
- Package broadcast main() (if declared) → loads and runs it
- Error → no entry point found
Rule 3: Broadcasted Main is Execution-Only
Broadcasted main() methods cannot be called from code.
· ❌ Not from other files
· ❌ Not from same file
· ❌ Not from same class
· ✅ Only executable by interpreter as entry point
Rule 4: Any File Can Trigger Execution
Any file in the package can execute the broadcasted main().
Complete Examples
Example 1: Standard Package
File Structure:
myapp/
├── logic.cod # Broadcasts main()
├── dev.cod # Executes broadcast
├── test.cod # Executes broadcast
└── prod.cod # Executes broadcast
Code:
// File: logic.cod (broadcaster)
unit my.app (main: AppLogic)
AppLogic {
share main() {
outln("App running...")
// Business logic here
}
}
// File: dev.cod (executor)
unit my.app
// No main() → will execute AppLogic.main()
// File: test.cod (executor with local main)
unit my.app
TestRunner {
share main() { // Local main wins (Priority 1)
outln("Running tests...")
}
}
// File: prod.cod (executor)
unit my.app
// No main() → will execute AppLogic.main()
Execution Results:
$ cod dev.cod
> App running... (Runs broadcast)
$ cod test.cod
> Running tests... (Runs local main, overrides broadcast)
$ cod prod.cod
> App running... (Runs broadcast)
Example 2: Library with Demo
File Structure:
mathlib/
├── library.cod # Main library logic
├── demo.cod # Example usage
└── benchmark.cod # Performance test
Code:
// File: library.cod
unit math.lib (main: MathLibrary)
MathLibrary {
// ❌ Cannot be called (broadcasted)
share main() {
outln("Math Library v1.0")
showExamples()
}
// ✅ Can be called
share add(a: int, b: int) -> int {
return a + b
}
// ✅ Can be called
share showExamples() {
outln("2 + 3 = " + add(2, 3))
}
}
// File: demo.cod
unit math.lib
Demo {
// Local main overrides broadcast
share main() {
math := MathLibrary()
outln("Demo: " + math.add(5, 7))
}
}
// File: benchmark.cod
unit math.lib
// No main() → executes MathLibrary.main()
Execution:
$ cod library.cod
> Math Library v1.0
> 2 + 3 = 5
$ cod demo.cod
> Demo: 12 (Local main runs)
$ cod benchmark.cod
> Math Library v1.0 (Runs broadcast)
> 2 + 3 = 5
Example 3: Web Application
File Structure:
webserver/
├── server.cod # Main server logic
├── dev.cod # Development mode
├── prod.cod # Production mode
└── health.cod # Health check (special)
Code:
// File: server.cod
unit web.app (main: WebServer)
WebServer {
// Execution-only entry point
share main() {
loadConfig()
setupRoutes()
startServer() // Blocks forever
}
// Callable methods
share loadConfig() { ... }
share setupRoutes() { ... }
share healthCheck() -> bool { ... }
}
// File: dev.cod
unit web.app
// Could set: DEBUG=true, PORT=3000
// Then runs WebServer.main()
// File: prod.cod
unit web.app
// Could set: PORT=80, WORKERS=4
// Then runs WebServer.main()
// File: health.cod
unit web.app
HealthMonitor {
// Special case: doesn't start server, just checks
share main() {
server := WebServer()
healthy := server.healthCheck() // ✅ Can call this
outln("Healthy: " + healthy)
}
}
Execution:
$ cod dev.cod
> [Starts server in dev mode]
$ cod prod.cod
> [Starts server in production mode]
$ cod health.cod
> Healthy: true (Runs local HealthMonitor.main())
Example 4: Error Cases
Multiple Broadcasts (Error):
// File A:
unit my.pkg (main: App1) // ❌ ERROR: Already declared in File B
// File B:
unit my.pkg (main: App2) // First one wins? Error?
Calling Broadcasted Main (Error):
// File: caller.cod
unit my.app
Caller {
share test() {
AppLogic.main() // ❌ ERROR: Cannot call broadcasted main()
}
}
No Entry Point (Error):
// File: empty.cod
unit my.app
// No local main, no package broadcast
$ cod empty.cod
Error: No executable main() found
Package 'my.app' has no broadcast entry point.
Add to any file: unit my.app (main: ClassName)
Rule Summary Table:
Scenario What Happens Example
File has main() Runs local main test.cod runs tests
File has no main(), package has broadcast Runs broadcasted main dev.cod runs AppLogic.main()
File has no main(), no broadcast Error empty.cod fails
Trying to call broadcasted main() Error Caller.test() fails
Multiple broadcasts in package First wins? Error? Design decision needed
Key Benefits:
- Consistency: One way to run the package
- Flexibility: Files can override with local main()
- Separation: Logic vs execution points
- Tooling: Different files for different purposes
- Clarity: Explicit broadcast declaration
Philosophy:
"One canonical way to run the package, accessible from anywhere in the package, overrideable when needed."
This is clean, practical, and elegantly simple!
Top comments (0)