Design Principles
This document outlines the fundamental design principles that guide the development of the Phaser programming language. These principles inform decisions across all aspects of the language, from Grammar Specification to Error Handling and the Compilation Pipeline.
Core Language Principles
Explicit Over Implicit
All behavior should be clear and unambiguous. Avoid magic, hidden behaviors, or implicit conversions that could surprise users. When in doubt, require explicit declaration.
Readability Counts
Prioritize clarity and human comprehension over brevity. Code is read far more often than it is written.
Simplicity Over Cleverness
Avoid overly complex solutions. Simple, straightforward code is easier to understand, debug, and maintain. Design features intuitively so the language behaves as users expect, following the principle of least astonishment. Simple isn’t always easy. We strive for the simplest solution that meets our needs but no simpler than that. We don’t want to unduly shift the burden of complexity onto our users.
One Way to Do It
Prefer a single, canonical approach to solving common problems. This reduces cognitive load and makes code more predictable and maintainable across projects.
Local Reasoning
Code should be understandable without requiring knowledge of distant context. Dependencies should be clear, and side effects should be minimized and obvious. There’s no spooky action at a distance.
Pareto Principle - Make the Common Case Easy and the Advanced Case Possible
The Pareto Principle, also known as the 80/20 rule, suggests that 80% of effects come from 20% of causes. In programming, this means focusing on the most impactful features and optimizing them while accepting that some less critical aspects may remain less optimized.
Security Through Capability-Based Design
Adopt capability-based security principles where possible. Grant components and users only the minimum privileges necessary to accomplish their tasks. This principle of least privilege reduces attack surface and contains potential damage from security breaches or bugs.
Best Practices
Fail Fast
Detect and report errors as early as possible. Catch problems at parse time, compile time, or early runtime rather than allowing invalid states to propagate.
Clear Error Messages
Errors should provide actionable information. Include context about what went wrong and suggest corrective actions when possible.
Consistency
Maintain consistent naming conventions, patterns, and structures throughout the language. This reduces friction when switching between different parts of code.
Composability
Design features to work well together. Prefer orthogonal, small composable pieces over monolithic features.
Minimize Surprise
Design features intuitively. Following principle of least astonishment ensures that the language behaves as users expect.