{"action":"created","issue":{"url":"https://api.github.com/repos/vavr-io/vavr/issues/2086","repository_url":"https://api.github.com/repos/vavr-io/vavr","labels_url":"https://api.github.com/repos/vavr-io/vavr/issues/2086/labels{/name}","comments_url":"https://api.github.com/repos/vavr-io/vavr/issues/2086/comments","events_url":"https://api.github.com/repos/vavr-io/vavr/issues/2086/events","html_url":"https://github.com/vavr-io/vavr/issues/2086","id":257855218,"number":2086,"title":"Support for concurrent recursive function memoization","user":{"login":"smillies","id":8183111,"avatar_url":"https://avatars2.githubusercontent.com/u/8183111?v=4","gravatar_id":"","url":"https://api.github.com/users/smillies","html_url":"https://github.com/smillies","followers_url":"https://api.github.com/users/smillies/followers","following_url":"https://api.github.com/users/smillies/following{/other_user}","gists_url":"https://api.github.com/users/smillies/gists{/gist_id}","starred_url":"https://api.github.com/users/smillies/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/smillies/subscriptions","organizations_url":"https://api.github.com/users/smillies/orgs","repos_url":"https://api.github.com/users/smillies/repos","events_url":"https://api.github.com/users/smillies/events{/privacy}","received_events_url":"https://api.github.com/users/smillies/received_events","type":"User","site_admin":false},"labels":[{"id":204492036,"url":"https://api.github.com/repos/vavr-io/vavr/labels/feature","name":"feature","color":"009800","default":false},{"id":480743485,"url":"https://api.github.com/repos/vavr-io/vavr/labels/%C2%ABvavr-core%C2%BB","name":"«vavr-core»","color":"f7f7f7","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/vavr-io/vavr/milestones/21","html_url":"https://github.com/vavr-io/vavr/milestone/21","labels_url":"https://api.github.com/repos/vavr-io/vavr/milestones/21/labels","id":1644052,"number":21,"title":"vavr-1.0.0","description":"A collecting vessel for a future Javaslang release that contains features which change the current API.","creator":{"login":"danieldietrich","id":743833,"avatar_url":"https://avatars0.githubusercontent.com/u/743833?v=4","gravatar_id":"","url":"https://api.github.com/users/danieldietrich","html_url":"https://github.com/danieldietrich","followers_url":"https://api.github.com/users/danieldietrich/followers","following_url":"https://api.github.com/users/danieldietrich/following{/other_user}","gists_url":"https://api.github.com/users/danieldietrich/gists{/gist_id}","starred_url":"https://api.github.com/users/danieldietrich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danieldietrich/subscriptions","organizations_url":"https://api.github.com/users/danieldietrich/orgs","repos_url":"https://api.github.com/users/danieldietrich/repos","events_url":"https://api.github.com/users/danieldietrich/events{/privacy}","received_events_url":"https://api.github.com/users/danieldietrich/received_events","type":"User","site_admin":false},"open_issues":101,"closed_issues":44,"state":"open","created_at":"2016-03-14T19:29:37Z","updated_at":"2017-09-27T07:57:12Z","due_on":null,"closed_at":null},"comments":13,"created_at":"2017-09-14T21:01:12Z","updated_at":"2017-09-27T17:27:45Z","closed_at":null,"author_association":"NONE","body":"Vavr already supports non-concurrent function memoization. As I happen to have written a concurrent recursive function memoizer some time ago, I will attach it as a patch for you to decide if it's worth including something like this in Vavr. I have ported the code from ordinary Java (CompletableFuture) to (I hope idiomatic) use of Vavr constructs (Promise, Future):\r\n[concurrent-recursive-function-memoization-patch.zip](https://github.com/vavr-io/vavr/files/1304548/concurrent-recursive-function-memoization-patch.zip)\r\n\r\nUsage example with good old Fibonacci sequence (doesn't actually show concurrent calls, but should be enough to illustrate the use):\r\n\r\n```\r\nimport io.vavr.Function1;\r\nimport java.math.BigInteger;\r\n\r\nimport static io.vavr.concurrent.Future.successful;\r\n\r\npublic class Fibonacci {\r\n    private static final Future<BigInteger> ONE = successful(BigInteger.ONE); // some shorthand\r\n    private final Function1<Integer, Future<BigInteger>> fibMem;  // a thread-safe, concurrently memoized recursive function\r\n\r\n    public Fibonacci() {\r\n        fibMem = MemoizedConcurrently.of(this::fib);\r\n        assert fibMem instanceof MemoizedConcurrently;\r\n    }\r\n\r\n    // fib delegates recursive calls to its memoizing version\r\n    // in good functional style we use the monadic operations flatMap and map on the Future\r\n    public Future<BigInteger> fib(int n) {\r\n        if (n <= 2) return ONE;\r\n        return fibMem.apply(n - 1).flatMap(x ->  // x = fib(n-1)\r\n                fibMem.apply(n - 2).map(y ->     // y = fib(n-2)\r\n                        x.add(y)));              // return x + y\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        Fibonacci fibonacci = new Fibonacci(); // shared instance that supports concurrent calls to fib(int)\r\n        Future<BigInteger> fibonacciNumber = fibonacci.fib(200_000); // Look Ma: linear runtime without StackOverflowError!\r\n        System.out.println(fibonacciNumber.get()); // block here\r\n    }\r\n}\r\n```\r\nMy original blog post about this topic is [here](http://sebastian-millies.blogspot.de/2016/05/concurrent-recursive-function.html)."},"comment":{"url":"https://api.github.com/repos/vavr-io/vavr/issues/comments/332595552","html_url":"https://github.com/vavr-io/vavr/issues/2086#issuecomment-332595552","issue_url":"https://api.github.com/repos/vavr-io/vavr/issues/2086","id":332595552,"user":{"login":"danieldietrich","id":743833,"avatar_url":"https://avatars0.githubusercontent.com/u/743833?v=4","gravatar_id":"","url":"https://api.github.com/users/danieldietrich","html_url":"https://github.com/danieldietrich","followers_url":"https://api.github.com/users/danieldietrich/followers","following_url":"https://api.github.com/users/danieldietrich/following{/other_user}","gists_url":"https://api.github.com/users/danieldietrich/gists{/gist_id}","starred_url":"https://api.github.com/users/danieldietrich/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danieldietrich/subscriptions","organizations_url":"https://api.github.com/users/danieldietrich/orgs","repos_url":"https://api.github.com/users/danieldietrich/repos","events_url":"https://api.github.com/users/danieldietrich/events{/privacy}","received_events_url":"https://api.github.com/users/danieldietrich/received_events","type":"User","site_admin":false},"created_at":"2017-09-27T17:27:45Z","updated_at":"2017-09-27T17:27:45Z","author_association":"OWNER","body":"> (And Future.fromCompletableFuture() cannot be used, because it blocks.)\r\n\r\nThis could be considered as bug. We need a version that asynchronously completes the wrapping future. I will create an issue."}}
{"actor":{"display_login":"danieldietrich"}}