{"action":"created","comment":{"url":"https://api.github.com/repos/scalaz/scalaz/pulls/comments/193506215","pull_request_review_id":126491223,"id":193506215,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDE5MzUwNjIxNQ==","diff_hunk":"@@ -0,0 +1,70 @@\n+package scalaz.effect\n+\n+import java.util.concurrent.TimeUnit\n+\n+import org.openjdk.jmh.annotations._\n+\n+import scala.{ Array, Boolean, Int, Unit }\n+import scala.collection.immutable.Range\n+import scala.Predef.{ genericArrayOps }\n+\n+import scalaz.Void\n+\n+@State(Scope.Thread)\n+@BenchmarkMode(Array(Mode.Throughput))\n+@OutputTimeUnit(TimeUnit.SECONDS)\n+class ArrayFillBenchmarks {\n+  @Param(Array(\"10000\"))\n+  var size: Int = _\n+\n+  def createTestArray: Array[Int] = Range.inclusive(1, size).toArray.reverse\n+\n+  @Benchmark\n+  def scalazArrayFill() = {\n+    import IOBenchmarks.unsafePerformIO\n+\n+    def arrayFill(array: Array[Int]): KleisliIO[Void, Int, Int] = {\n+      val condition = KleisliIO.lift[Void, Int, Boolean]((i: Int) => i < array.length)\n+\n+      KleisliIO.whileDo(condition)(KleisliIO.impureVoid[Int, Int] { (i: Int) =>\n+        array.update(i, i)\n+\n+        i + 1\n+      })\n+    }\n+\n+    unsafePerformIO(\n+      for {\n+        array <- IO.sync(createTestArray)\n+        _     <- arrayFill(array)(0)\n+      } yield ()\n+    )\n+  }\n+  @Benchmark\n+  def catsArrayFill() = {\n+    import cats.effect.IO\n+\n+    def arrayFill(array: Array[Int])(i: Int): IO[Unit] =\n+      if (i >= array.length) IO.unit\n+      else IO(array.update(i, i)).flatMap(_ => arrayFill(array)(i + 1))\n+\n+    (for {\n+      array <- IO(createTestArray)\n+      _     <- arrayFill(array)(0)\n+    } yield ()).unsafeRunSync()\n+  }\n+  @Benchmark\n+  def monixArrayFill() = {\n+    import monix.eval.Task\n+    import IOBenchmarks.monixScheduler\n+\n+    def arrayFill(array: Array[Int])(i: Int): Task[Unit] =\n+      if (i >= array.length) Task.unit\n+      else Task.eval(array.update(i, i)).flatMap(_ => arrayFill(array)(i + 1))\n+\n+    (for {\n+      array <- Task.eval(createTestArray)\n+      _     <- arrayFill(array)(0)\n+    } yield ()).toIO.unsafeRunSync()","path":"benchmarks/src/main/scala/scalaz/effect/ArrayFillBenchmark.scala","position":68,"original_position":68,"commit_id":"41f19b34a603e9ebda5d377e836f00c008f2c3b7","original_commit_id":"41f19b34a603e9ebda5d377e836f00c008f2c3b7","user":{"login":"jdegoes","id":156745,"node_id":"MDQ6VXNlcjE1Njc0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/156745?v=4","gravatar_id":"","url":"https://api.github.com/users/jdegoes","html_url":"https://github.com/jdegoes","followers_url":"https://api.github.com/users/jdegoes/followers","following_url":"https://api.github.com/users/jdegoes/following{/other_user}","gists_url":"https://api.github.com/users/jdegoes/gists{/gist_id}","starred_url":"https://api.github.com/users/jdegoes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdegoes/subscriptions","organizations_url":"https://api.github.com/users/jdegoes/orgs","repos_url":"https://api.github.com/users/jdegoes/repos","events_url":"https://api.github.com/users/jdegoes/events{/privacy}","received_events_url":"https://api.github.com/users/jdegoes/received_events","type":"User","site_admin":false},"body":"Fixed, although it has zero impact on performance because it's dominated by the individual operations themselves.","created_at":"2018-06-06T18:05:18Z","updated_at":"2018-06-06T18:05:18Z","html_url":"https://github.com/scalaz/scalaz/pull/1857#discussion_r193506215","pull_request_url":"https://api.github.com/repos/scalaz/scalaz/pulls/1857","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/comments/193506215"},"html":{"href":"https://github.com/scalaz/scalaz/pull/1857#discussion_r193506215"},"pull_request":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/1857"}},"in_reply_to_id":193345350},"pull_request":{"url":"https://api.github.com/repos/scalaz/scalaz/pulls/1857","id":192775876,"node_id":"MDExOlB1bGxSZXF1ZXN0MTkyNzc1ODc2","html_url":"https://github.com/scalaz/scalaz/pull/1857","diff_url":"https://github.com/scalaz/scalaz/pull/1857.diff","patch_url":"https://github.com/scalaz/scalaz/pull/1857.patch","issue_url":"https://api.github.com/repos/scalaz/scalaz/issues/1857","number":1857,"state":"open","locked":false,"title":"Add Kleisli arrow with operation fusion for imported (impure) functions","user":{"login":"jdegoes","id":156745,"node_id":"MDQ6VXNlcjE1Njc0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/156745?v=4","gravatar_id":"","url":"https://api.github.com/users/jdegoes","html_url":"https://github.com/jdegoes","followers_url":"https://api.github.com/users/jdegoes/followers","following_url":"https://api.github.com/users/jdegoes/following{/other_user}","gists_url":"https://api.github.com/users/jdegoes/gists{/gist_id}","starred_url":"https://api.github.com/users/jdegoes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdegoes/subscriptions","organizations_url":"https://api.github.com/users/jdegoes/orgs","repos_url":"https://api.github.com/users/jdegoes/repos","events_url":"https://api.github.com/users/jdegoes/events{/privacy}","received_events_url":"https://api.github.com/users/jdegoes/received_events","type":"User","site_admin":false},"body":"Based on the work of John Hughes in [Programming with Arrows](http://www.cse.chalmers.se/~rjmh/Papers/arrows.pdf) and similar in spirit to TraneIO's [Arrows](https://github.com/traneio/arrows), this pull request introduces an arrow abstraction for importing and composing effectful code in a purely-functional way.\r\n\r\nIn this work, Kleisli arrows are specialized to `IO`. While the behavior and interface of `KleisliIO` is identical to `Kleisli` on the `IO` type, a separate constructor allows impure functions to be imported as `A => B`, without any `IO` overhead. This constructor, in turn, allows fusion of core arrow operations when both left and right side are impure functions. The result is a dramatic reduction in overhead for performance-critical sections of code composed entirely with impure functions.\r\n\r\nAlthough designed and optimized for fusion of impure functions, `KleisliIO` works seamlessly with pure functions lifted into the structure. Sections that can be optimized _are_ optimized, while still allowing incorporation of the greater flexibility and expressiveness that `IO` provides.\r\n\r\nCurrent major limitations include:\r\n\r\n - Lack of support for recursive combinator\r\n - Lack of support for infinite / lazy composition \r\n - Lack of support for asynchronous\r\n - There are virtually no error combinators\r\n\r\nBecause of the support for `IO`, these limitations do not actually hinder expressibility. Anything that cannot currently be done in `KleisliIO` directly can be done in `IO` and lifted into `KleisliIO`.\r\n\r\nWhile almost universally faster for every class of problem it can be used to solve, there is definitely overhead associated with arrow-based programming—mainly all the tupling/eithering that occurs as information and conditions are propagated forward. Future work should be able to eliminate this overhead and show greater performance increases on very complex code written in the arrow style.\r\n\r\nThis pull request does not include a test suite but @wi101, who assisted with implementing and optimizing this code, has developed a test suite and will contribute it separately.","created_at":"2018-06-05T17:04:52Z","updated_at":"2018-06-06T18:05:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"76f0e31d1d9f5831247512882acf99b288e3d525","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":385574322,"node_id":"MDU6TGFiZWwzODU1NzQzMjI=","url":"https://api.github.com/repos/scalaz/scalaz/labels/scalaz8","name":"scalaz8","color":"fbca04","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/scalaz/scalaz/pulls/1857/commits","review_comments_url":"https://api.github.com/repos/scalaz/scalaz/pulls/1857/comments","review_comment_url":"https://api.github.com/repos/scalaz/scalaz/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scalaz/scalaz/issues/1857/comments","statuses_url":"https://api.github.com/repos/scalaz/scalaz/statuses/41f19b34a603e9ebda5d377e836f00c008f2c3b7","head":{"label":"jdegoes:kleisli_io","ref":"kleisli_io","sha":"41f19b34a603e9ebda5d377e836f00c008f2c3b7","user":{"login":"jdegoes","id":156745,"node_id":"MDQ6VXNlcjE1Njc0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/156745?v=4","gravatar_id":"","url":"https://api.github.com/users/jdegoes","html_url":"https://github.com/jdegoes","followers_url":"https://api.github.com/users/jdegoes/followers","following_url":"https://api.github.com/users/jdegoes/following{/other_user}","gists_url":"https://api.github.com/users/jdegoes/gists{/gist_id}","starred_url":"https://api.github.com/users/jdegoes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdegoes/subscriptions","organizations_url":"https://api.github.com/users/jdegoes/orgs","repos_url":"https://api.github.com/users/jdegoes/repos","events_url":"https://api.github.com/users/jdegoes/events{/privacy}","received_events_url":"https://api.github.com/users/jdegoes/received_events","type":"User","site_admin":false},"repo":{"id":111010947,"node_id":"MDEwOlJlcG9zaXRvcnkxMTEwMTA5NDc=","name":"scalaz","full_name":"jdegoes/scalaz","owner":{"login":"jdegoes","id":156745,"node_id":"MDQ6VXNlcjE1Njc0NQ==","avatar_url":"https://avatars1.githubusercontent.com/u/156745?v=4","gravatar_id":"","url":"https://api.github.com/users/jdegoes","html_url":"https://github.com/jdegoes","followers_url":"https://api.github.com/users/jdegoes/followers","following_url":"https://api.github.com/users/jdegoes/following{/other_user}","gists_url":"https://api.github.com/users/jdegoes/gists{/gist_id}","starred_url":"https://api.github.com/users/jdegoes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jdegoes/subscriptions","organizations_url":"https://api.github.com/users/jdegoes/orgs","repos_url":"https://api.github.com/users/jdegoes/repos","events_url":"https://api.github.com/users/jdegoes/events{/privacy}","received_events_url":"https://api.github.com/users/jdegoes/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jdegoes/scalaz","description":"An extension to the core Scala library for functional programming.","fork":true,"url":"https://api.github.com/repos/jdegoes/scalaz","forks_url":"https://api.github.com/repos/jdegoes/scalaz/forks","keys_url":"https://api.github.com/repos/jdegoes/scalaz/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jdegoes/scalaz/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jdegoes/scalaz/teams","hooks_url":"https://api.github.com/repos/jdegoes/scalaz/hooks","issue_events_url":"https://api.github.com/repos/jdegoes/scalaz/issues/events{/number}","events_url":"https://api.github.com/repos/jdegoes/scalaz/events","assignees_url":"https://api.github.com/repos/jdegoes/scalaz/assignees{/user}","branches_url":"https://api.github.com/repos/jdegoes/scalaz/branches{/branch}","tags_url":"https://api.github.com/repos/jdegoes/scalaz/tags","blobs_url":"https://api.github.com/repos/jdegoes/scalaz/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jdegoes/scalaz/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jdegoes/scalaz/git/refs{/sha}","trees_url":"https://api.github.com/repos/jdegoes/scalaz/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jdegoes/scalaz/statuses/{sha}","languages_url":"https://api.github.com/repos/jdegoes/scalaz/languages","stargazers_url":"https://api.github.com/repos/jdegoes/scalaz/stargazers","contributors_url":"https://api.github.com/repos/jdegoes/scalaz/contributors","subscribers_url":"https://api.github.com/repos/jdegoes/scalaz/subscribers","subscription_url":"https://api.github.com/repos/jdegoes/scalaz/subscription","commits_url":"https://api.github.com/repos/jdegoes/scalaz/commits{/sha}","git_commits_url":"https://api.github.com/repos/jdegoes/scalaz/git/commits{/sha}","comments_url":"https://api.github.com/repos/jdegoes/scalaz/comments{/number}","issue_comment_url":"https://api.github.com/repos/jdegoes/scalaz/issues/comments{/number}","contents_url":"https://api.github.com/repos/jdegoes/scalaz/contents/{+path}","compare_url":"https://api.github.com/repos/jdegoes/scalaz/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jdegoes/scalaz/merges","archive_url":"https://api.github.com/repos/jdegoes/scalaz/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jdegoes/scalaz/downloads","issues_url":"https://api.github.com/repos/jdegoes/scalaz/issues{/number}","pulls_url":"https://api.github.com/repos/jdegoes/scalaz/pulls{/number}","milestones_url":"https://api.github.com/repos/jdegoes/scalaz/milestones{/number}","notifications_url":"https://api.github.com/repos/jdegoes/scalaz/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jdegoes/scalaz/labels{/name}","releases_url":"https://api.github.com/repos/jdegoes/scalaz/releases{/id}","deployments_url":"https://api.github.com/repos/jdegoes/scalaz/deployments","created_at":"2017-11-16T19:06:04Z","updated_at":"2018-05-25T12:03:21Z","pushed_at":"2018-06-05T17:33:21Z","git_url":"git://github.com/jdegoes/scalaz.git","ssh_url":"git@github.com:jdegoes/scalaz.git","clone_url":"https://github.com/jdegoes/scalaz.git","svn_url":"https://github.com/jdegoes/scalaz","homepage":"http://scalaz.github.io/scalaz/#scaladoc","size":96783,"stargazers_count":13,"watchers_count":13,"language":"Scala","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":2,"open_issues":1,"watchers":13,"default_branch":"series/7.3.x"}},"base":{"label":"scalaz:series/8.0.x","ref":"series/8.0.x","sha":"8876b9a16937411b0fcaae8fd613d968d52dd657","user":{"login":"scalaz","id":183416,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE4MzQxNg==","avatar_url":"https://avatars0.githubusercontent.com/u/183416?v=4","gravatar_id":"","url":"https://api.github.com/users/scalaz","html_url":"https://github.com/scalaz","followers_url":"https://api.github.com/users/scalaz/followers","following_url":"https://api.github.com/users/scalaz/following{/other_user}","gists_url":"https://api.github.com/users/scalaz/gists{/gist_id}","starred_url":"https://api.github.com/users/scalaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalaz/subscriptions","organizations_url":"https://api.github.com/users/scalaz/orgs","repos_url":"https://api.github.com/users/scalaz/repos","events_url":"https://api.github.com/users/scalaz/events{/privacy}","received_events_url":"https://api.github.com/users/scalaz/received_events","type":"Organization","site_admin":false},"repo":{"id":474633,"node_id":"MDEwOlJlcG9zaXRvcnk0NzQ2MzM=","name":"scalaz","full_name":"scalaz/scalaz","owner":{"login":"scalaz","id":183416,"node_id":"MDEyOk9yZ2FuaXphdGlvbjE4MzQxNg==","avatar_url":"https://avatars0.githubusercontent.com/u/183416?v=4","gravatar_id":"","url":"https://api.github.com/users/scalaz","html_url":"https://github.com/scalaz","followers_url":"https://api.github.com/users/scalaz/followers","following_url":"https://api.github.com/users/scalaz/following{/other_user}","gists_url":"https://api.github.com/users/scalaz/gists{/gist_id}","starred_url":"https://api.github.com/users/scalaz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalaz/subscriptions","organizations_url":"https://api.github.com/users/scalaz/orgs","repos_url":"https://api.github.com/users/scalaz/repos","events_url":"https://api.github.com/users/scalaz/events{/privacy}","received_events_url":"https://api.github.com/users/scalaz/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scalaz/scalaz","description":"An extension to the core Scala library for functional programming.","fork":false,"url":"https://api.github.com/repos/scalaz/scalaz","forks_url":"https://api.github.com/repos/scalaz/scalaz/forks","keys_url":"https://api.github.com/repos/scalaz/scalaz/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scalaz/scalaz/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scalaz/scalaz/teams","hooks_url":"https://api.github.com/repos/scalaz/scalaz/hooks","issue_events_url":"https://api.github.com/repos/scalaz/scalaz/issues/events{/number}","events_url":"https://api.github.com/repos/scalaz/scalaz/events","assignees_url":"https://api.github.com/repos/scalaz/scalaz/assignees{/user}","branches_url":"https://api.github.com/repos/scalaz/scalaz/branches{/branch}","tags_url":"https://api.github.com/repos/scalaz/scalaz/tags","blobs_url":"https://api.github.com/repos/scalaz/scalaz/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scalaz/scalaz/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scalaz/scalaz/git/refs{/sha}","trees_url":"https://api.github.com/repos/scalaz/scalaz/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scalaz/scalaz/statuses/{sha}","languages_url":"https://api.github.com/repos/scalaz/scalaz/languages","stargazers_url":"https://api.github.com/repos/scalaz/scalaz/stargazers","contributors_url":"https://api.github.com/repos/scalaz/scalaz/contributors","subscribers_url":"https://api.github.com/repos/scalaz/scalaz/subscribers","subscription_url":"https://api.github.com/repos/scalaz/scalaz/subscription","commits_url":"https://api.github.com/repos/scalaz/scalaz/commits{/sha}","git_commits_url":"https://api.github.com/repos/scalaz/scalaz/git/commits{/sha}","comments_url":"https://api.github.com/repos/scalaz/scalaz/comments{/number}","issue_comment_url":"https://api.github.com/repos/scalaz/scalaz/issues/comments{/number}","contents_url":"https://api.github.com/repos/scalaz/scalaz/contents/{+path}","compare_url":"https://api.github.com/repos/scalaz/scalaz/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scalaz/scalaz/merges","archive_url":"https://api.github.com/repos/scalaz/scalaz/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scalaz/scalaz/downloads","issues_url":"https://api.github.com/repos/scalaz/scalaz/issues{/number}","pulls_url":"https://api.github.com/repos/scalaz/scalaz/pulls{/number}","milestones_url":"https://api.github.com/repos/scalaz/scalaz/milestones{/number}","notifications_url":"https://api.github.com/repos/scalaz/scalaz/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scalaz/scalaz/labels{/name}","releases_url":"https://api.github.com/repos/scalaz/scalaz/releases{/id}","deployments_url":"https://api.github.com/repos/scalaz/scalaz/deployments","created_at":"2010-01-16T06:18:51Z","updated_at":"2018-06-06T16:32:33Z","pushed_at":"2018-06-06T17:00:35Z","git_url":"git://github.com/scalaz/scalaz.git","ssh_url":"git@github.com:scalaz/scalaz.git","clone_url":"https://github.com/scalaz/scalaz.git","svn_url":"https://github.com/scalaz/scalaz","homepage":"https://scalaz.github.io/scalaz/#scaladoc","size":97697,"stargazers_count":3697,"watchers_count":3697,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":620,"mirror_url":null,"archived":false,"open_issues_count":187,"license":{"key":"other","name":"Other","spdx_id":null,"url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":620,"open_issues":187,"watchers":3697,"default_branch":"series/7.3.x"}},"_links":{"self":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/1857"},"html":{"href":"https://github.com/scalaz/scalaz/pull/1857"},"issue":{"href":"https://api.github.com/repos/scalaz/scalaz/issues/1857"},"comments":{"href":"https://api.github.com/repos/scalaz/scalaz/issues/1857/comments"},"review_comments":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/1857/comments"},"review_comment":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scalaz/scalaz/pulls/1857/commits"},"statuses":{"href":"https://api.github.com/repos/scalaz/scalaz/statuses/41f19b34a603e9ebda5d377e836f00c008f2c3b7"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"jdegoes"}}