{"action":"opened","number":4454,"pull_request":{"url":"https://api.github.com/repos/scala/scala/pulls/4454","id":33515204,"html_url":"https://github.com/scala/scala/pull/4454","diff_url":"https://github.com/scala/scala/pull/4454.diff","patch_url":"https://github.com/scala/scala/pull/4454.patch","issue_url":"https://api.github.com/repos/scala/scala/issues/4454","number":4454,"state":"open","locked":false,"title":"Make lambda body public rather than using static accessor","user":{"login":"retronym","id":65551,"avatar_url":"https://avatars.githubusercontent.com/u/65551?v=3","gravatar_id":"","url":"https://api.github.com/users/retronym","html_url":"https://github.com/retronym","followers_url":"https://api.github.com/users/retronym/followers","following_url":"https://api.github.com/users/retronym/following{/other_user}","gists_url":"https://api.github.com/users/retronym/gists{/gist_id}","starred_url":"https://api.github.com/users/retronym/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/retronym/subscriptions","organizations_url":"https://api.github.com/users/retronym/orgs","repos_url":"https://api.github.com/users/retronym/repos","events_url":"https://api.github.com/users/retronym/events{/privacy}","received_events_url":"https://api.github.com/users/retronym/received_events","type":"User","site_admin":false},"body":"Under -Ydelambdafy:method (the basis of the upcoming \"indylambda\"\ntranslation for -target:jvm-1.8), an anonymous function is currently\nencoded as:\n\n 1. a private method containing the lambda's code\n 2. a public, static accessor method that allows access to 1 from\n    other classes, namely:\n 3. an anonymous class capturing free variables and implementing\n    the suitable FunctionN interface.\n\nIn our prototypes of indylambda, we do away with 3, instead deferring\ncreating of this class to JDK8's LambdaMetafactory by way of an\ninvokedynamic instruction at the point of lambda capture. This\nfacility can use a private method as the lambda target; access is\nmediated by the runtime-provided instance of\n`java.lang.invoke.MethodHandles.Lookup` that confers the privelages\nof the lambda capture call site to the generated implementation class.\nIndeed, The java compiler uses this to emit private lambda body\nmethods.\n\nHowever, there are two Scala specific factors that make this\na little troublesome.\n\nFirst, Scala's optimizer may want to inline the lambda capture\ncall site into a new enclosing class. In general, this isn't a\nsafe optimization, as `invokedynamic` instructions have call-site\nspecific semantics. But we will rely the ability to inline like\nthis in order to eliminate closures altogether where possible.\n\nSecond, to support lambda deserialization, the Java compiler creates\na synthetic method `$dersializeLamda$` in each class that captures\nthem, just to be able to get the suitable access to spin up an\nanoymous class with access to the private method. It only needs\nto do this for functional interfaces that extends Serializable,\nwhich is the exception rather than the rule. But in Scala, *every*\nfunction must support serialization, so blindly copying the Java\napproach will lead to some code bloat.\n\nI have prototyped a hybrid approach to these challenges: use the\nprivate method directly where it is allowed, but fall back to\nusing the accessor method in a generic lambda deserializer or\nin call sites that have been inlined into a new enclosing class.\n\nHowever, the most straight forward approach is to simply emit the\nlambda bodies as public (with an mangled name and with the SYHTNETIC\nflag) and use them in all cases. That is what is done in this commit.\n\nThis does moves us one step backwards from the goals of SI-7085,\nbut it doesn't seem sensible to incur the inconvenience from locking\ndown one small part of our house when we don't have a plan or the\nbudget to complete that job.\n\nThe REPL has some fancy logic to decompile the bodys of lambdas\n(`:javap -fun C#m`) which needed tweaking to accomodate this change.\nI haven't tried to make this backwards compatible with the old\nencoding as `-Ydelambdafy:method` is still experimental.","created_at":"2015-04-17T05:19:01Z","updated_at":"2015-04-17T05:19:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/scala/scala/pulls/4454/commits","review_comments_url":"https://api.github.com/repos/scala/scala/pulls/4454/comments","review_comment_url":"https://api.github.com/repos/scala/scala/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scala/scala/issues/4454/comments","statuses_url":"https://api.github.com/repos/scala/scala/statuses/a593bcde0eb2e475cf07c8ae86a9dc63421e796c","head":{"label":"retronym:topic/indylambda-no-accessor","ref":"topic/indylambda-no-accessor","sha":"a593bcde0eb2e475cf07c8ae86a9dc63421e796c","user":{"login":"retronym","id":65551,"avatar_url":"https://avatars.githubusercontent.com/u/65551?v=3","gravatar_id":"","url":"https://api.github.com/users/retronym","html_url":"https://github.com/retronym","followers_url":"https://api.github.com/users/retronym/followers","following_url":"https://api.github.com/users/retronym/following{/other_user}","gists_url":"https://api.github.com/users/retronym/gists{/gist_id}","starred_url":"https://api.github.com/users/retronym/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/retronym/subscriptions","organizations_url":"https://api.github.com/users/retronym/orgs","repos_url":"https://api.github.com/users/retronym/repos","events_url":"https://api.github.com/users/retronym/events{/privacy}","received_events_url":"https://api.github.com/users/retronym/received_events","type":"User","site_admin":false},"repo":{"id":2902104,"name":"scala","full_name":"retronym/scala","owner":{"login":"retronym","id":65551,"avatar_url":"https://avatars.githubusercontent.com/u/65551?v=3","gravatar_id":"","url":"https://api.github.com/users/retronym","html_url":"https://github.com/retronym","followers_url":"https://api.github.com/users/retronym/followers","following_url":"https://api.github.com/users/retronym/following{/other_user}","gists_url":"https://api.github.com/users/retronym/gists{/gist_id}","starred_url":"https://api.github.com/users/retronym/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/retronym/subscriptions","organizations_url":"https://api.github.com/users/retronym/orgs","repos_url":"https://api.github.com/users/retronym/repos","events_url":"https://api.github.com/users/retronym/events{/privacy}","received_events_url":"https://api.github.com/users/retronym/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/retronym/scala","description":"The Scala programming language","fork":true,"url":"https://api.github.com/repos/retronym/scala","forks_url":"https://api.github.com/repos/retronym/scala/forks","keys_url":"https://api.github.com/repos/retronym/scala/keys{/key_id}","collaborators_url":"https://api.github.com/repos/retronym/scala/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/retronym/scala/teams","hooks_url":"https://api.github.com/repos/retronym/scala/hooks","issue_events_url":"https://api.github.com/repos/retronym/scala/issues/events{/number}","events_url":"https://api.github.com/repos/retronym/scala/events","assignees_url":"https://api.github.com/repos/retronym/scala/assignees{/user}","branches_url":"https://api.github.com/repos/retronym/scala/branches{/branch}","tags_url":"https://api.github.com/repos/retronym/scala/tags","blobs_url":"https://api.github.com/repos/retronym/scala/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/retronym/scala/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/retronym/scala/git/refs{/sha}","trees_url":"https://api.github.com/repos/retronym/scala/git/trees{/sha}","statuses_url":"https://api.github.com/repos/retronym/scala/statuses/{sha}","languages_url":"https://api.github.com/repos/retronym/scala/languages","stargazers_url":"https://api.github.com/repos/retronym/scala/stargazers","contributors_url":"https://api.github.com/repos/retronym/scala/contributors","subscribers_url":"https://api.github.com/repos/retronym/scala/subscribers","subscription_url":"https://api.github.com/repos/retronym/scala/subscription","commits_url":"https://api.github.com/repos/retronym/scala/commits{/sha}","git_commits_url":"https://api.github.com/repos/retronym/scala/git/commits{/sha}","comments_url":"https://api.github.com/repos/retronym/scala/comments{/number}","issue_comment_url":"https://api.github.com/repos/retronym/scala/issues/comments{/number}","contents_url":"https://api.github.com/repos/retronym/scala/contents/{+path}","compare_url":"https://api.github.com/repos/retronym/scala/compare/{base}...{head}","merges_url":"https://api.github.com/repos/retronym/scala/merges","archive_url":"https://api.github.com/repos/retronym/scala/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/retronym/scala/downloads","issues_url":"https://api.github.com/repos/retronym/scala/issues{/number}","pulls_url":"https://api.github.com/repos/retronym/scala/pulls{/number}","milestones_url":"https://api.github.com/repos/retronym/scala/milestones{/number}","notifications_url":"https://api.github.com/repos/retronym/scala/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/retronym/scala/labels{/name}","releases_url":"https://api.github.com/repos/retronym/scala/releases{/id}","created_at":"2011-12-02T23:04:11Z","updated_at":"2015-03-12T17:11:19Z","pushed_at":"2015-04-17T05:18:46Z","git_url":"git://github.com/retronym/scala.git","ssh_url":"git@github.com:retronym/scala.git","clone_url":"https://github.com/retronym/scala.git","svn_url":"https://github.com/retronym/scala","homepage":"http://www.scala-lang.org/","size":100404,"stargazers_count":4,"watchers_count":4,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":6,"forks":0,"open_issues":6,"watchers":4,"default_branch":"master"}},"base":{"label":"scala:2.11.x","ref":"2.11.x","sha":"b730937493f8f25c985b1a4cf5fcfb7fc16092a4","user":{"login":"scala","id":57059,"avatar_url":"https://avatars.githubusercontent.com/u/57059?v=3","gravatar_id":"","url":"https://api.github.com/users/scala","html_url":"https://github.com/scala","followers_url":"https://api.github.com/users/scala/followers","following_url":"https://api.github.com/users/scala/following{/other_user}","gists_url":"https://api.github.com/users/scala/gists{/gist_id}","starred_url":"https://api.github.com/users/scala/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala/subscriptions","organizations_url":"https://api.github.com/users/scala/orgs","repos_url":"https://api.github.com/users/scala/repos","events_url":"https://api.github.com/users/scala/events{/privacy}","received_events_url":"https://api.github.com/users/scala/received_events","type":"Organization","site_admin":false},"repo":{"id":2888818,"name":"scala","full_name":"scala/scala","owner":{"login":"scala","id":57059,"avatar_url":"https://avatars.githubusercontent.com/u/57059?v=3","gravatar_id":"","url":"https://api.github.com/users/scala","html_url":"https://github.com/scala","followers_url":"https://api.github.com/users/scala/followers","following_url":"https://api.github.com/users/scala/following{/other_user}","gists_url":"https://api.github.com/users/scala/gists{/gist_id}","starred_url":"https://api.github.com/users/scala/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scala/subscriptions","organizations_url":"https://api.github.com/users/scala/orgs","repos_url":"https://api.github.com/users/scala/repos","events_url":"https://api.github.com/users/scala/events{/privacy}","received_events_url":"https://api.github.com/users/scala/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scala/scala","description":"The Scala programming language","fork":false,"url":"https://api.github.com/repos/scala/scala","forks_url":"https://api.github.com/repos/scala/scala/forks","keys_url":"https://api.github.com/repos/scala/scala/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scala/scala/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scala/scala/teams","hooks_url":"https://api.github.com/repos/scala/scala/hooks","issue_events_url":"https://api.github.com/repos/scala/scala/issues/events{/number}","events_url":"https://api.github.com/repos/scala/scala/events","assignees_url":"https://api.github.com/repos/scala/scala/assignees{/user}","branches_url":"https://api.github.com/repos/scala/scala/branches{/branch}","tags_url":"https://api.github.com/repos/scala/scala/tags","blobs_url":"https://api.github.com/repos/scala/scala/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scala/scala/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scala/scala/git/refs{/sha}","trees_url":"https://api.github.com/repos/scala/scala/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scala/scala/statuses/{sha}","languages_url":"https://api.github.com/repos/scala/scala/languages","stargazers_url":"https://api.github.com/repos/scala/scala/stargazers","contributors_url":"https://api.github.com/repos/scala/scala/contributors","subscribers_url":"https://api.github.com/repos/scala/scala/subscribers","subscription_url":"https://api.github.com/repos/scala/scala/subscription","commits_url":"https://api.github.com/repos/scala/scala/commits{/sha}","git_commits_url":"https://api.github.com/repos/scala/scala/git/commits{/sha}","comments_url":"https://api.github.com/repos/scala/scala/comments{/number}","issue_comment_url":"https://api.github.com/repos/scala/scala/issues/comments{/number}","contents_url":"https://api.github.com/repos/scala/scala/contents/{+path}","compare_url":"https://api.github.com/repos/scala/scala/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scala/scala/merges","archive_url":"https://api.github.com/repos/scala/scala/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scala/scala/downloads","issues_url":"https://api.github.com/repos/scala/scala/issues{/number}","pulls_url":"https://api.github.com/repos/scala/scala/pulls{/number}","milestones_url":"https://api.github.com/repos/scala/scala/milestones{/number}","notifications_url":"https://api.github.com/repos/scala/scala/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scala/scala/labels{/name}","releases_url":"https://api.github.com/repos/scala/scala/releases{/id}","created_at":"2011-12-01T05:02:34Z","updated_at":"2015-04-17T01:44:38Z","pushed_at":"2015-04-17T05:19:01Z","git_url":"git://github.com/scala/scala.git","ssh_url":"git@github.com:scala/scala.git","clone_url":"https://github.com/scala/scala.git","svn_url":"https://github.com/scala/scala","homepage":"http://www.scala-lang.org/","size":190263,"stargazers_count":4002,"watchers_count":4002,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1030,"mirror_url":null,"open_issues_count":21,"forks":1030,"open_issues":21,"watchers":4002,"default_branch":"2.11.x"}},"_links":{"self":{"href":"https://api.github.com/repos/scala/scala/pulls/4454"},"html":{"href":"https://github.com/scala/scala/pull/4454"},"issue":{"href":"https://api.github.com/repos/scala/scala/issues/4454"},"comments":{"href":"https://api.github.com/repos/scala/scala/issues/4454/comments"},"review_comments":{"href":"https://api.github.com/repos/scala/scala/pulls/4454/comments"},"review_comment":{"href":"https://api.github.com/repos/scala/scala/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scala/scala/pulls/4454/commits"},"statuses":{"href":"https://api.github.com/repos/scala/scala/statuses/a593bcde0eb2e475cf07c8ae86a9dc63421e796c"}},"merged":false,"mergeable":null,"mergeable_state":"unknown","merged_by":null,"comments":0,"review_comments":0,"commits":1,"additions":49,"deletions":99,"changed_files":3}}