{"id":30462840,"url":"https://github.com/domix/dmx-fun","last_synced_at":"2026-04-01T20:47:17.611Z","repository":{"id":303167548,"uuid":"1011540757","full_name":"domix/dmx-fun","owner":"domix","description":"This repository contains a collection of implementations and experiments exploring functional programming constructions in Java. ","archived":false,"fork":false,"pushed_at":"2026-03-02T06:09:10.000Z","size":3019,"stargazers_count":1,"open_issues_count":12,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-02T09:43:02.905Z","etag":null,"topics":["functional-programming","gradle","java","java-25","railway-oriented-programming"],"latest_commit_sha":null,"homepage":"https://domix.github.io/dmx-fun/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/domix.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"domix"}},"created_at":"2025-07-01T01:36:58.000Z","updated_at":"2026-03-02T06:09:12.000Z","dependencies_parsed_at":"2025-07-06T05:03:35.871Z","dependency_job_id":"a6fb8ea7-f7ab-45e5-896e-4eb45732a5a8","html_url":"https://github.com/domix/dmx-fun","commit_stats":null,"previous_names":["domix/dmx-fun"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/domix/dmx-fun","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domix%2Fdmx-fun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domix%2Fdmx-fun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domix%2Fdmx-fun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domix%2Fdmx-fun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/domix","download_url":"https://codeload.github.com/domix/dmx-fun/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/domix%2Fdmx-fun/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30278153,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T20:45:49.896Z","status":"ssl_error","status_checked_at":"2026-03-08T20:45:49.525Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","gradle","java","java-25","railway-oriented-programming"],"created_at":"2025-08-23T23:02:42.562Z","updated_at":"2026-04-01T20:47:17.602Z","avatar_url":"https://github.com/domix.png","language":"Java","funding_links":["https://github.com/sponsors/domix"],"categories":[],"sub_categories":[],"readme":"\n# λ dmx-fun: Functional Programming Constructions in Java\n\n\u003cimg width=\"1536\" height=\"1024\" alt=\"image\" src=\"https://github.com/user-attachments/assets/cab675c2-c8ca-4017-903f-6790309750e8\" /\u003e\n\nThis repository contains a collection of implementations and experiments exploring **functional programming constructions in Java**. The goal is to demonstrate how functional paradigms—such as immutability, pure functions, higher-order functions, currying, and more—can be expressed in Java, a traditionally object-oriented language.\n\n## 🔍 Purpose\n\nWhile Java is not a purely functional language, modern features like lambda expressions, streams, and the `Optional` and `CompletableFuture` APIs allow for elegant and expressive functional-style programming. This project aims to:\n\n- Explore functional programming principles in Java\n- Showcase reusable constructions inspired by functional languages\n- Experiment with Java libraries that support functional programming\n- Serve as a reference and learning resource for developers\n\n## 📦 What's Included\n\nExamples and implementations may include:\n\n- Function composition and higher-order functions  \n- Currying and partial application  \n- Immutable data structures  \n- Functional error handling (e.g., using `Try`, `Result`, or `Option`)  \n- Lazy evaluation  \n- Monads and functors (in a Java-friendly context)  \n- Functional streams and pipelines  \n\n## 🛠 Technologies\n\n- Java 25+\n- Gradle\n- Spock for testing  \n- [Vavr](https://www.vavr.io/) or similar libraries for functional data types (optional)  \n\n## 🤝 Contributions\n\nContributions, discussions, and suggestions are welcome! Feel free to open issues or submit pull requests.\n\n## 📄 License\n\nThis project is licensed under the Apache License. See the [LICENSE](./LICENSE) file for more details.\n\n## 🛠️ Usage\n\n\n### Installation\n\nThis library is available on Maven Central. To use it, include the following dependency to your project's configuration file:\n\n#### Maven\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecodes.domix\u003c/groupId\u003e\n    \u003cartifactId\u003efun\u003c/artifactId\u003e\n    \u003cversion\u003e0.0.11\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Gradle\n\n```groovy\nimplementation(\"codes.domix:fun:0.0.11\")\n```\n### Usage\n\nAssuming you have imported the library, you can start using it in your code.\n\nLet's start with a simple example. You have a method that validates a user's email, in a method like this:\n\n```java\n    protected Result\u003cCreateUserCommand, String\u003e isValidEmail(\n        CreateUserCommand command\n    ) {\n        var email = command.email();\n        if (email == null || email.isBlank()) {\n            return Result.err(\"Provided email is either null or blank\");\n        }\n        boolean emailMatches = EMAIL_PATTERN\n            .matcher(email)\n            .matches();\n\n        if (!emailMatches) {\n            return Result.err(\"Invalid email\");\n        }\n\n        return Result.ok(command);\n    }\n```\n\nIn the previous example, we are using the `Result` type from the `fun` library. This type is a simple wrapper around an `Optional` that provides additional methods for handling errors.\n\nIn a nutshell, the `Result` type allows you to express a computation that may fail, and handle the error case in a type-safe way.\n\nIf everything goes well, the `Result` will contain the original value, in case of error, it will contain an error message.\n\nNow you want to validate the user's password, with similar logic. You can create a new method like this:\n\n```java\n    protected Result\u003cCreateUserCommand, String\u003e isValidPassword(\n        CreateUserCommand command\n    ) {\n\n        var password = command.password();\n        if (password == null) {\n            return Result.err(\"Provided password is null\");\n        }\n        boolean validPassword = PASSWORD_PATTERN\n            .matcher(password)\n            .matches();\n\n        if (!validPassword) {\n            return Result.err(\"Invalid password.\");\n        }\n\n        return Result.ok(command);\n    }\n```\n\nAs you can see, the `Result` type is used to express the result of the validation. \n\nNow we can combine both validations in a single method. You can do it like this:\n\n```java\n    public Result\u003cUser, String\u003e createUser(CreateUserCommand command) {\n        return this.isValidEmail(command)\n            .flatMap(this::isValidPassword)\n            .flatMap(this.userRepository::createUser);\n    }\n```\n\nIn this case, the validation is performed in two steps, and the result of the first step is used as the input for the second step.\n\nIn the end, the result of the whole validation process is used to create the user in the database.\n\nThe main benefit of this approach is that the validation logic is encapsulated in a single method, and it can be reused in other places.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomix%2Fdmx-fun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdomix%2Fdmx-fun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdomix%2Fdmx-fun/lists"}