This project serves as a demo application showcasing how to apply functional programming patterns in Go. While Go traditionally follows an imperative, non-functional style, this project explores how concepts like monads, chaining, and folds can be utilized to write cleaner and more expressive code in Go.
The main branch contains the classic, non-functional Go implementation. Each step towards functional programming is available in separate branches, showing a gradual transformation of the codebase.
- Project Overview
- Demo Steps
- Setup and Installation
- Running the Application
- Generating Code
- Testing and Coverage
- Project Structure
- Further Reading
- Contributions
- License
This project demonstrates the evolution from non-functional Go to functional Go programming style. It follows a step-by-step approach, with each step available as a separate branch for clarity. The transformations include:
- Classic Non-Functional Style (Main Branch): The baseline implementation using Go's traditional imperative style.
- Step 1 – Applying Monad: The
OrdersStorageis refactored to leverage a Monad, encapsulating state and behavior in a composable way. - Step 2 – Chaining Calls: Functional chaining is introduced, improving readability and reducing boilerplate.
- Step 3 – Simplification with Fold: Code is further simplified by introducing the
foldoperation, which consolidates transformations. - Step 4 – Full Functional Refactor: The remaining parts of the codebase are refactored to fully adopt functional programming patterns.
For detailed explanations of each step and additional instructions, visit the project's GitHub page.
- Main Branch: Classic non-functional implementation.
- Step 1 Branch: Introduction of Monads with
OrdersStorage. - Step 2 Branch: Functional chaining of calls and operations.
- Step 3 Branch: Code simplification using the
foldoperation. - Step 4 Branch: Full adoption of functional programming patterns.
- Go SDK 1.23.5: Ensure Go is installed. Download it here.
- Mockery: Install Mockery for generating mocks:
go install github.com/vektra/mockery/v2@latest
- Wire: Install Wire for dependency injection:
go install github.com/google/wire/cmd/wire@latest
To run the demo application, navigate to the desired branch and use the following command:
go run ./cmdUse Wire to auto-generate dependency injection code:
cd internal/app && go generate ./Generate mock implementations for interfaces with Mockery:
mockery --all --output=mocksRun tests and generate a coverage report to ensure the codebase's quality:
# Run tests and generate coverage data
go test -cover -coverpkg=$(go list ./... | grep -v '/mocks' | grep -v '/cmd' | tr '\n' ',') ./... -coverprofile=coverage.out
# View the coverage report in a browser
go tool cover -html=coverage.out├── cmd/ # Entry point for the application
├── internal/ # Application's internal implementation
│ ├── app/ # Core application logic
│ ├── domain/ # Business entities and logic
│ ├── mocks/ # Auto-generated mocks for testing
│ └── ... # Additional packages
└── tests/ # Unit and integration tests
For step-by-step explanations, detailed instructions, and discussions on functional programming in Go, please refer to the official project documentation.
As this is a demo application, contributions are welcome! If you’d like to contribute:
- Fork the repository.
- Create a feature branch:
git checkout -b feature/<feature-name>
- Commit your changes:
git commit -am 'Add new feature: <feature-description>' - Push to the branch:
git push origin feature/<feature-name>
- Open a Pull Request.
This project is licensed under the Mozilla Public License 2.0 (MPL-2.0).
Under this license:
- You are free to use, modify, and distribute this project.
- You must retain attribution to the original author in all distributed copies or modified code.
- Modifications to the source code must also be made available under the same license.
For more details, see the LICENSE file or read the full text of the MPL-2.0 here.
