Implementing Nested Expressions in MediLang: A Developer's Journey
This is the first in a series of posts documenting the development of MediLang, a programming language designed specifically for healthcare applications.
The Challenge
When we started building MediLang, we knew we needed a way to express complex medical calculations in a way that felt natural to healthcare professionals. Traditional programming languages often fall short when it comes to medical-specific operations and units. Our solution? Build a language with first-class support for medical concepts.
Our Development Journey
Phase 1: Laying the Foundation (May 10-11)
- PR #1: Initial project setup and core parser infrastructure
- PRs #3-4: Documentation and build system configuration
Phase 2: Building the Core (May 12-17)
- PR #5: First implementation of the recursive descent parser
- PRs #6-8: Multiple iterations to perfect the parser implementation
- Added comprehensive test coverage
- Improved error handling and recovery
- Enhanced documentation and examples
Phase 3: Advanced Features (May 18-24)
- PRs #9-10: Implemented custom operator precedence
- Added support for medical operators (
of,per) - Detailed documentation of operator behavior
- PR #11: Nested expressions and block statements
- Full support for complex nested calculations
- Improved syntax error messages
- Edge case handling and optimizations
Key Features
Medical-Specific Operators
MediLang introduces operators that make medical calculations more intuitive:
// Calculate total medication dose
let total_medication = 2 of 500mg; // 1000mg total
// Calculate infusion rate
let infusion_rate = 1000mL per 8hr; // 125 mL/hr
// Complex calculation with proper precedence
let adjusted_dose = (weight * 2.5mg) + (age * 0.1mg) of medication;
Error Messages That Help
We've put significant effort into making error messages helpful and actionable:
Error: Type mismatch in expression
--> patient.medi:12:25
|
12 | let dose = 2 of "500mg";
| ^ Expected number after 'of', found string
|
= help: Remove quotes to use a numeric literal
Technical Deep Dive
The Parser Architecture
Our recursive descent parser was carefully designed to handle the unique requirements of medical calculations:
- Operator Precedence: Custom rules for medical operators
- Error Recovery: Graceful handling of syntax errors
- Performance: Optimized for the most common medical calculation patterns
Testing Strategy
We implemented a comprehensive test suite covering: - Basic arithmetic operations - Nested expressions - Edge cases in medical calculations - Error conditions and recovery
What We Learned
-
Domain-Specific Languages Matter Building operators that match medical professionals' mental models makes the language more accessible.
-
Error Messages Are Crucial Clear, actionable error messages significantly improve the development experience.
-
Iterative Development Wins Multiple small PRs with focused changes led to better code quality and easier reviews.
What's Next
Our roadmap includes:
- Pattern matching for medical data types
- Built-in support for common medical calculations
- Enhanced IDE tooling and autocompletion
- Standard library of medical functions
Get Involved
We're just getting started! Join our community: - Try out the latest build - Contribute to our GitHub repository - Join the discussion in our Discord server
Full Development History
For a detailed account of all changes, see our CHANGELOG.md.