{"id":758,"date":"2015-03-21T19:41:25","date_gmt":"2015-03-21T18:41:25","guid":{"rendered":"http:\/\/benjiweber.co.uk\/blog\/?p=758"},"modified":"2015-03-21T19:41:25","modified_gmt":"2015-03-21T18:41:25","slug":"yield-return-in-java","status":"publish","type":"post","link":"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/","title":{"rendered":"Yield Return in Java"},"content":{"rendered":"<p class=\"lead\">A feature often missed in Java by c# developers is <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/9k7k7cf0.aspx\">yield return<\/a><\/p>\n<p>It can be used to create Iterators\/<a href=\"http:\/\/en.wikipedia.org\/wiki\/Generator_(computer_programming)#C.23\">Generators<\/a> easily. For example, we can print the infinite series of positive numbers like so:<\/p>\n<pre lang=\"csharp\">\r\npublic static void Main()\r\n{\r\n    foreach (int i in positiveIntegers()) \r\n    {\r\n        Console.WriteLine(i);    \r\n    }\r\n}\r\n    \r\npublic static IEnumerable<int> positiveIntegers()\r\n{\r\n    int i = 0;\r\n    while (true) yield return ++i;\r\n}\r\n<\/pre>\n<p>Annoyingly, I don&#8217;t think there&#8217;s a good way to implement this in Java, because it relies on compiler transformations.<\/p>\n<p>If we want to use it in Java there are three main approaches I am aware of, which have various drawbacks. <\/p>\n<ul>\n<li>Compile-time transformations &#8211; like <a href=\"https:\/\/github.com\/peichhorn\/lombok-pg\">lombok-pg<\/a><\/li>\n<li>Bytecode transformations &#8211; like <a href=\"https:\/\/code.google.com\/p\/infomancers-collections\/\">infomancers-collections<\/a><\/li>\n<li>Threads &#8211; like <a href=\"http:\/\/svn.jimblackler.net\/jimblackler\/trunk\/IdeaProjects\/YieldAdapter\/\">Jim Blackler&#8217;s implementation<\/a>\n<\/ul>\n<p>The compile-time approach means your code can&#8217;t be compiled with javac alone, which is a significant disadvantage. <\/p>\n<p>The bytecode transformation approach means magic going on that you can&#8217;t easily understand by following the code. I&#8217;ve been burnt by obscure problems with aspect-oriented-programming frameworks using bytecode manipulation enough times to avoid it.<\/p>\n<p>The threads approach has a runtime performance cost of extra threads. We also need to dispose of the created threads or we will leak memory.<\/p>\n<p>I don&#8217;t personally want the feature enough to put up with the drawbacks of any of these approaches. <\/p>\n<p>That being said, if you were willing to put up with one of these approaches, can we make them look cleaner in our code.<\/p>\n<p>I&#8217;m going to ignore the lombok\/compile-time transformation approach as it allows pretty much anything. <\/p>\n<p>Both the other approaches above require writing valid Java. The threads approach is particularly verbose, but there is a <a href=\"https:\/\/github.com\/domlachowicz\/java-generators\">wrapper<\/a> which simplify it down to returning an anonymous implementation of an abstract class that provides yield \/ yieldBreak methods. e.g.<\/p>\n<pre lang=\"java\">\r\npublic Iterable<Integer> oneToFive() {\r\n    return new Yielder<Integer>() {\r\n        protected void yieldNextCore() {\r\n            for (int i = 1; i < 10; i++) {\r\n                if (i == 6) yieldBreak();\r\n                yieldReturn(i);\r\n            }\r\n        }\r\n    };\t\r\n}\r\n<\/pre>\n<p>This is quite ugly compared to the c# equivalent. We can make it cleaner now we have lambdas, but we can't use the same approach as above. <\/p>\n<p>I'm going to use the threading approach for this example as it's easier to see what's going on.<\/p>\n<p>Let's say we have an interface Foo which extends Runnable, and provides an additional default method.<\/p>\n<pre lang=\"java\">\r\ninterface Foo extends Runnable {\r\n    default void bar() {}\r\n}\r\n<\/pre>\n<p>If we create an instance of this as an anonymous inner class we can call the bar() method from our implementation of run();<\/p>\n<pre lang=\"java\">\r\nFoo foo = new Foo() {\r\n    public void run() {\r\n        bar();\r\n    }\r\n};\r\n<\/pre>\n<p>However, if we create our implementation with a lambda this no longer compiles<\/p>\n<pre lang=\"java\">\r\nFoo foo = () -> {\r\n    bar(); \/\/ java: cannot find symbol. symbol: method bar()\r\n};\r\n<\/pre>\n<p>This means we'll have to take a different approach. Here's something we can do, that is significantly cleaner thanks to lambdas. <\/p>\n<pre lang=\"java\">\r\npublic Yielderable<Integer> oneToFive() {\r\n    return yield -> {\r\n        for (int i = 1; i < 10; i++) {\r\n            if (i == 6) yield.breaking();\r\n            yield.returning(i);\r\n        }\r\n    };\r\n}\r\n<\/pre>\n<p>How can this work? Note the change of the method return type from Iterable to a new interface Yielderable. This means we can return any structurally equivalent lambda. Since we want to create an Iterable we'll need to extend Iterable to have it behave as an Iterable.<\/p>\n<pre lang=\"java\">\r\npublic interface Yielderable<T> extends Iterable<T> { \/* ... *\/ }\r\n<\/pre>\n<p>The <a href=\"http:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/Iterable.html\">Iterable interface<\/a> already has an abstract method iterator(), which means we'll need to implement that if we want to add a new method to build our yield statement, while still remaining a lambda-compatible single method interface. <\/p>\n<p>We can add a default implementation of iterator() that executes a yield definition defined by a new abstract method.<\/p>\n<pre lang=\"java\">\r\npublic interface Yielderable<T> extends Iterable<T> {\r\n    void execute(YieldDefinition<T> builder);\r\n\r\n    default Iterator<T> iterator() {  \/* ... *\/  }\r\n}\r\n<\/pre>\n<p>We now have a single abstract method, still compatible with a lambda. It accepts one parameter - a YieldDefinition. This means we can call methods defined on YieldDefinition in our lambda implementation. The default iterator() method can create an instance of a YieldDefinition and invoke the execute method for us.<\/p>\n<pre lang=\"java\">\r\npublic interface Yielderable<T> extends Iterable<T> {\r\n    void execute(YieldDefinition<T> builder);\r\n\r\n    default Iterator<T> iterator() {\r\n\t    YieldDefinition<T> definition = new YieldDefinition<>()\r\n\t    execute(definition);\r\n\t    \/\/... more implementation needed.\r\n    }\r\n}\r\n<\/pre>\n<p>Our YieldDefinition class provides the returning(value) and breaking() methods to use in our yield definition.<\/p>\n<pre lang=\"java\">\r\nclass YieldDefinition<T> {\r\n    public void returning(T value) { \/* ... *\/ }\r\n\r\n    public void breaking() { \/* ... *\/ }\r\n}\r\n\r\n<\/pre>\n<p>Now Java can infer the type of the lambda parameter, allowing us to call them in the lambda body. You should even get code completion in your IDE of choice.<\/p>\n<p><img src=\"http:\/\/files.benjiweber.co.uk\/b\/yieldreturn.png\"\/><\/p>\n<p>I have made a full implementation of the threaded approach using with above lambda definition style <a href=\"https:\/\/github.com\/benjiman\/yield-java\">if you are interested.<\/a><\/p>\n<p>There's some more <a href=\"https:\/\/github.com\/benjiman\/yield-java\/blob\/master\/src\/test\/java\/com\/benjiweber\/yield\/YieldTest.java\">examples of what is possible<\/a> and the <a href=\"https:\/\/github.com\/benjiman\/yield-java\/blob\/master\/src\/main\/java\/com\/benjiweber\/yield\/Yielderable.java\">full implementation<\/a> for reference.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A feature often missed in Java by c# developers is yield return It can be used to create Iterators\/Generators easily. For example, we can print the infinite series of positive numbers like so: public static void Main() { foreach (int i in positiveIntegers()) { Console.WriteLine(i); } } public static IEnumerable positiveIntegers() { int i =&#8230;  <a href=\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/\" class=\"more-link\" title=\"Read Yield Return in Java\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[25,8],"tags":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Yield Return in Java - Benji&#039;s Blog\" \/>\n<meta property=\"og:description\" content=\"A feature often missed in Java by c# developers is yield return It can be used to create Iterators\/Generators easily. For example, we can print the infinite series of positive numbers like so: public static void Main() { foreach (int i in positiveIntegers()) { Console.WriteLine(i); } } public static IEnumerable positiveIntegers() { int i =... Read more &raquo;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/\" \/>\n<meta property=\"og:site_name\" content=\"Benji&#039;s Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-21T18:41:25+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/files.benjiweber.co.uk\/b\/yieldreturn.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/\",\"name\":\"Benji&#039;s Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/benjiweber.co.uk\/blog\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/files.benjiweber.co.uk\/b\/yieldreturn.png\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/#webpage\",\"url\":\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/\",\"name\":\"Yield Return in Java - Benji&#039;s Blog\",\"isPartOf\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/#primaryimage\"},\"datePublished\":\"2015-03-21T18:41:25+00:00\",\"dateModified\":\"2015-03-21T18:41:25+00:00\",\"author\":{\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/benjiweber.co.uk\/blog\/2015\/03\/21\/yield-return-in-java\/\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#\/schema\/person\/45ecb36b51f4ce99e6929d2d31ca5c09\",\"name\":\"benji\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/benjiweber.co.uk\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/05fb47b31a0b329e1b790074a9b624ef?s=96&d=mm&r=g\",\"caption\":\"benji\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","amp_enabled":true,"_links":{"self":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/758"}],"collection":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=758"}],"version-history":[{"count":10,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/758\/revisions"}],"predecessor-version":[{"id":848,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/posts\/758\/revisions\/848"}],"wp:attachment":[{"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/benjiweber.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}