{"id":20533855,"url":"https://github.com/anicolaspp/nsource","last_synced_at":"2026-04-22T09:03:41.690Z","repository":{"id":95258096,"uuid":"150472197","full_name":"anicolaspp/nSource","owner":"anicolaspp","description":"A composable library for collections","archived":false,"fork":false,"pushed_at":"2018-10-01T18:21:41.000Z","size":275,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-16T13:20:58.762Z","etag":null,"topics":["academia","functional-programming","lazy-loading","streams"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anicolaspp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-26T18:31:01.000Z","updated_at":"2018-10-01T18:21:42.000Z","dependencies_parsed_at":"2023-03-10T23:45:22.342Z","dependency_job_id":null,"html_url":"https://github.com/anicolaspp/nSource","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anicolaspp%2FnSource","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anicolaspp%2FnSource/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anicolaspp%2FnSource/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anicolaspp%2FnSource/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anicolaspp","download_url":"https://codeload.github.com/anicolaspp/nSource/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242138887,"owners_count":20078006,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["academia","functional-programming","lazy-loading","streams"],"created_at":"2024-11-16T00:24:06.040Z","updated_at":"2026-04-22T09:03:36.656Z","avatar_url":"https://github.com/anicolaspp.png","language":"Java","readme":"![Logo](https://github.com/anicolaspp/nSource/blob/master/lazy%20nSource%20..png)\n\n\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.anicolaspp/nSource/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.anicolaspp/nSource)\n[![Build Status](https://travis-ci.org/anicolaspp/nSource.svg?branch=master)](https://travis-ci.org/anicolaspp/nSource)\n\n# nSource\n\n**nSource** is a small, stream-like, fully featured and functional library to chain computation stages on top of regular Java Collections. This library is intended as a case of study for lazy design and to demonstrate how laziness is an important part when building performant software.\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003ecom.github.anicolaspp\u003c/groupId\u003e\n  \u003cartifactId\u003enSource\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Features\n\n**nSource** has a few interesting characteristics.\n\n- it is lazy, until the last materialization stage.\n- its API is functional, so we can use declarative flow control.\n- it has a familiar API, by using stream-like naming.\n- It is optimized, so it operates on the minimum and only necessary elements of the underlying data source.\n\n## Usage\n\n**nSource** allows us to do the following. \n\n```java\nRunnableStage\u003cList\u003cString\u003e\u003e s = nsource\n                              .from(getNumbers())\n                              .filter(x-\u003e x % 2 == 0)\n                              .map(x-\u003e x.toString())\n                              .toList();\nList\u003cString\u003e f = s.run();\n```\n\nNotice that nothing happens until we call `.run()` of the corresponding `RunnableStage\u003c\u003e`. \n\nAs we can see, this library can be seen in a similar way to what `Java Streams` offer and even though the intention is not to replace Streams, the library shows how the inception of lazy desing is a building blog when building smart components that need to present good performance. \n\n## Stream-like API\n\nThe main component of the **nSource** is `ComposableStage\u003c\u003e` and the followings are some of the present combinators. \n\n```java\n    public \u003cB\u003e ComposableStage\u003cB\u003e map(Function\u003cA, B\u003e fn)\n    public ComposableStage\u003cA\u003e filter(Predicate\u003cA\u003e predicate)\n    public ComposableStage\u003cA\u003e take(int n)\n    public ComposableStage\u003cA\u003e takeWhile(Predicate\u003cA\u003e predicate)\n    public RunnableStage\u003cList\u003cA\u003e\u003e toList()\n    public \u003cB\u003e RunnableStage\u003cB\u003e foldLeft(B zero, BiFunction\u003cA, B, B\u003e biFunction)\n    public RunnableStage\u003cDone\u003e forEach(Consumer\u003cA\u003e consumer)\n    public RunnableStage\u003cOptional\u003cA\u003e\u003e first()\n    public RunnableStage\u003cA\u003e firstOrDefault(Supplier\u003cA\u003e defaultValue)\n```\n\n***This is NOT the entire list***\n\nAs we can appreciate, it shares a lot with `Java Streams` but it holds on laziness as much as it can. \n\n**nSource** `ComposableStage\u003c\u003e` are meant to be used for chaining operations. However, once we get a `RunnableStage\u003c\u003e` we should not reuse the corresponding `ComposableStage\u003c\u003e`.  \n\n```java\nString name = ....\n\nRunnableStage\u003cInteger\u003e sum = nSource\n                              .from(getValues(...))\n                              .filter(v -\u003e v.name.equals(name))\n                              .map(v -\u003e v.getAge())\n                              .foldLeft(0, (a, b) -\u003e a + b);\n\nassert sum.run() == sum.run()\n```\n\nIn here, the computations happens only once (the first time we call `.run()` and the second time the value is reused internally. \n\nOn the other hand, the following might cause a source reuse, and that is not allowed. \n\n```java\nComposableStage\u003cList\u003cInteger\u003e\u003e stage = nSource\n                              .from(getValues(...))\n                              .filter(v -\u003e v.name.equals(name))\n                              .map(v -\u003e v.getAge());\n\nRunnableStage\u003cInteger\u003e sum = stage.foldLeft(0, (a, b) -\u003e a + b);\n\nRunnableStage\u003cDone\u003e printThem = stage.forEach(System.out::println);\n```\n\nThis is perfectly valid since nothing has been executed just yet, but then we should only be able to materialize exactly one of them (the first one to call `.run()`. \n\n```java\nprintThem.run();\n...\nint sumValue = sum.run(); // MaterializationException thrown here. \n```\n\nThe first one to be materialized wins.\n\n\u003e This library is not intended to be used in production, but to present implementation details on lazy and smart design/implementation. \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanicolaspp%2Fnsource","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanicolaspp%2Fnsource","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanicolaspp%2Fnsource/lists"}