A Scala educational project demonstrating different approaches to the same simple program: reading data from a CSV file, updating protagonist ages based on user input, and writing the results back.
This project serves as a comprehensive learning resource for Scala programming, showcasing how the same basic logic can be implemented using various programming paradigms, patterns, and libraries. Each version highlights different aspects of Scala and functional programming concepts.
All versions perform the same task:
- Read a CSV file containing protagonist data (first name, last name, age)
- Ask the user for an age increment value
- Update each protagonist's age
- Write the updated data back to the CSV file
The foundation version using straightforward, idiomatic Scala.
- Focus: Basic Scala features (objects, immutability, higher-order functions)
- Execution: Sequential, eager evaluation
- Key Concepts: Simple method calls, direct side effects
Demonstrates lazy evaluation and external library integration.
- Focus:
lazy valfor deferred computation, scala-csv library - Execution: Conditional—file read only if needed
- Key Concepts: Lazy evaluation, CSV library usage, resource optimization
Pure functional programming with referential transparency using Cats Effect.
- Focus: IO monad, effect system, pure functions
- Execution: Deferred—operations described, not executed until runtime
- Key Concepts: Referential transparency, IO monad, separation of description from execution
Manual dependency injection using function parameters.
- Focus: Testability through function parameter injection
- Execution: Sequential with injected I/O operations
- Key Concepts: Higher-order functions, manual DI, testing with mocks
Framework-assisted dependency injection using MacWire.
- Focus: Trait-based DI with compile-time wiring
- Execution: Sequential with trait-based abstraction
- Key Concepts: Traits as contracts, MacWire
wire[]macro, OOP-style DI
Scala 3's implicit context parameters for DI.
- Focus:
given/usingsyntax for implicit dependency resolution - Execution: Sequential with compiler-resolved dependencies
- Key Concepts: Context parameters, implicit resolution, Scala 3 features
Capability-based programming with context functions.
- Focus: Fine-grained capabilities, capture checking,
?->syntax - Execution: Sequential with explicit capability requirements
- Key Concepts: Context functions, capability-based security, type-level effects
Two variants demonstrating Future-based concurrency.
- FutureVersionWithAwait: Basic Future usage with blocking wait
- FutureVersionWithThreadPool: Custom thread pool with non-blocking callbacks
- Focus: Parallel execution, async/await patterns, ExecutionContext
- Execution: File reading and user input happen in parallel
- Key Concepts:
Future,Await, thread pools, concurrent I/O
Manual Future completion with Promise.
- Focus: Promise for explicit Future control
- Execution: Similar to Future but with manual completion
- Key Concepts:
Promise, manual async control, delegation pattern
Actor Model implementation using Apache Pekko.
- Focus: Actor-based concurrency, message passing
- Execution: Three independent actors communicating via messages
- Key Concepts: Actor Model, message protocols, asynchronous coordination
A minimal Future implementation showing how futures work under the hood.
- Purpose: Educational—demonstrates Future internals
- Not a program variant: Standalone example
- Key Concepts:
- Asynchronous computation execution
- Callback registration and execution
- Completion state management
- Try-based result handling
- Compare With:
FutureVersionandPromiseVersionto see how the concepts apply
Recommended study order:
- Start Here:
DefaultVersion.scala- Master the basics - Lazy Evaluation:
LazyScalaCSVVersion.scala- Understand deferred computation - Testing:
MUnitVersion.scala- Learn testable code design - Frameworks:
DIVersion.scala- Explore framework-assisted DI - Given/Using:
GivenUsingVersion.scala- Implicit parameters - Pure FP:
CatsEffectVersion.scala- Referential transparency and effect systems - Async Basics:
CustomFuture.scala- How futures work (supplement) - Concurrency:
FutureVersion.scala- Standard async patterns - Advanced Async:
PromiseVersion.scala- Manual control - Actor Model:
PekkoVersion.scala- Message-driven concurrency - Capabilities:
CapabilitiesVersion.scala- Context-based effects
Unit tests are provided for testable versions:
MUnitVersionSuite.scala- Tests for MUnitVersionDIVersionSuite.scala- Tests for DIVersionGivenUsingVersionSuite.scala- Tests for GivenUsingVersionCapabilitiesVersionSuite.scala- Tests for CapabilitiesVersion
Each version has a main() method (commented out with /* @main */). Uncomment one at a time to run.
Each version contains comprehensive Scaladoc comments explaining:
- What Scala features are demonstrated
- How the version differs from DefaultVersion
- Key concepts and patterns
- When to use each approach
- Step-by-step execution flow
Read the source files for detailed educational commentary!
GPL 3.0 - See LICENSE file for details
Maciej Gorywoda (makingthematrix@protonmail.com)
Happy Learning! 🎓
This project is designed for students learning Scala. Take your time with each version, understand the concepts, and see how the same problem can be solved in many different ways.