{"id":813,"date":"2017-12-14T15:54:27","date_gmt":"2017-12-14T15:54:27","guid":{"rendered":"http:\/\/smartfoxserver.com\/blog\/?p=813"},"modified":"2017-12-18T14:40:06","modified_gmt":"2017-12-18T14:40:06","slug":"server-side-extensions-with-lambda-expressions","status":"publish","type":"post","link":"https:\/\/smartfoxserver.com\/blog\/server-side-extensions-with-lambda-expressions\/","title":{"rendered":"Functional Java in server side Extensions"},"content":{"rendered":"<p>With the release of patch 2.13.1 SmartFoxServer 2X adds support for functional Java and lambdas in server side Extensions. In this article we&#8217;re going to take a closer look at how we can use lambdas in our server side code.<!--more--><\/p>\n<p>If you&#8217;re familiar with languages such as Python, Ruby or Javascript you have probably\u00a0used functions as any other object and pass them around as parameters to other functions and methods. Also you can inline anonymous functions that can be passed to any method requiring it.<\/p>\n<p>In Java this has never been possible until the release of JDK 8. Before that, developers could emulate a similar mechanism with anonymous classes, such as in the code below:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nThread thread = new Thread\r\n(\r\n\tnew Runnable()\r\n\t{\r\n\t\t@Override\r\n\t\tpublic void run()\r\n\t\t{\r\n\t\t\tSystem.out.println(&quot;Thread is running...&quot;);\r\n\t\t}\r\n\t}\r\n);\r\n\r\nthread.start();\r\n<\/pre>\n<p>This is a good example of the infamous &#8220;verbosity&#8221; in Java that is often complained about by developers. And it&#8217;s probably a fair criticism given that every time we want to pass a method around we have to create an anonymous class wrapping the actual method, and implement the &#8220;method&#8217;s interface&#8221; (i.e. the class the acts as template for the implementation we&#8217;re passing around).<\/p>\n<p>Now that Java supports lambdas (or anonymous functions) we can express the same functionality in a more readable way:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nThread thread = new Thread( () -&gt; { System.out.println(&quot;Thread is running...&quot;); } ); \r\n<\/pre>\n<p>What we&#8217;re doing here is defining an anonymous function that takes no parameters (hence the &#8220;()&#8221;) and inlining it after the arrow operator. In other words we can now define an anonymous function like this:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n(paramA, paramB) -&gt; { \/\/ body of the function };\r\n<\/pre>\n<p>and we can treat this as any other object in Java, pass it to other methods etc. In parenthesis we specify the arguments of the function, followed by the arrow operator (->), followed by the body of the function in curly brackets, as in any other method.<\/p>\n<h3>Functional interfaces<\/h3>\n<p>Before we proceed with using lambdas in SFS2X we need to mention <strong>functional interfaces<\/strong> which define the function in terms of parameter types and return value types. Essentially any interface with a single abstract method is also a <b>functional interface<\/b>.<\/p>\n<p>The new JDK 8 provides a lot of these to cover the basic needs of functional programming, such as empty functions, predicates and more. To illustrate how this works, we&#8217;ll implement a simple test that calculates the occurrence of certain characters in a String. For instance we may want to calculate all of the characters in a message, or just the alphanumeric ones, or maybe only the upper cases, etc.<\/p>\n<p>To do this we can create different functions that calculate different occurrences and pass them around as parameters. The following is our main method:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic int countCharacters(Function&lt;String, Integer&gt; fn, String str)\r\n{\r\n\tint count = fn.apply(str);\r\n\treturn count;\r\n}\r\n<\/pre>\n<p>Here we require two parameters: a function that takes a string and return an integer and the string to search. The <b>Function<\/b> type is a functional interface provided by the JDK (under the <em>java.util.function<\/em> package) and declared as <b>Function&lt;T, R&gt;<\/b> where <b>T<\/b> is the type of the input and <b>R<\/b> is the type of the return value.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nString testStr = &quot;This is a test string&quot;;\r\nFunction&lt;String, Integer&gt; myfn = (str) -&gt; { return str.length(); };\r\n\r\nint res = countCharacters(myfn, testStr);\r\nSystem.out.println(&quot;Result =&gt; &quot;+ res);\r\n\r\npublic int countCharacters(Function&lt;String, Integer&gt; fn, String inputStr)\r\n{\r\n\tint count = fn.apply(inputStr);\r\n\treturn count;\r\n}\r\n<\/pre>\n<p>Here we define a function that calculates the number of characters and then pass it to our main <em>countCharacter<\/em> method. This enables us to implement as many different functions as we need and dynamically pass them to count characters in multiple ways.<\/p>\n<p>We can also inline the function directly, if needed:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nint res = countCharacters((str) -&gt; { return str.length(); }, &quot;This is a test string&quot;);\r\nSystem.out.println(&quot;Result =&gt; &quot; + res);\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Integrating in SFS2X<\/h3>\n<p>Assuming you&#8217;re familiar with how Extensions work in Java, (<a href='http:\/\/docs2x.smartfoxserver.com\/ExtensionsJava\/quick-start' target='_blank'>if not please see here<\/a>)<br \/>\nthis code should look familiar:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class MyExtension extends SFSExtension\r\n{\r\n    @Override\r\n    public void init()\r\n    {\r\n         \/\/ Add a new Request Handler\r\n        addRequestHandler(&quot;echo&quot;, EchoHandler.class);\r\n    }\r\n \r\n    public class EchoHandler extends BaseClientRequestHandler\r\n    {\r\n        @Override\r\n        public void handleClientRequest(User sender, ISFSObject params)\r\n        {\r\n            send(&quot;echo&quot;, resObj, sender);\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>We create a request handler with the command &#8220;echo&#8221; and register it with the Extension. The handler in turn receives the request and sends the same data back to the client. <\/p>\n<p>With the new release the BaseClientRequestHandler class is now implementing a functional interface that looks like this:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@FunctionalInterface\r\npublic interface IClientRequestHandler\r\n{\r\n\tvoid handleClientRequest(User sender, ISFSObject params);\r\n}\r\n<\/pre>\n<p>Notice the <em>@FunctionalInterface<\/em> annotation. This isn&#8217;t mandatory and it&#8217;s more of an informative tool for developers as the compiler will detect functional interfaces regardless of the annotation.<\/p>\n<p>This is how we can translate the previous code in functional style:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class MyExtension extends SFSExtension\r\n{\r\n    @Override\r\n    public void init()\r\n    {\r\n         \/\/ Add a new Request Handler\r\n        addRequestHandler(&quot;echo&quot;, (sender, params) -&gt; { send(&quot;echo&quot;, resObj, sender) });\r\n    }\r\n}\r\n<\/pre>\n<p>We have eliminated the class definition entirely and since the method is very simple we can inline it directly. Alternatively we can use the double colon syntax (::) as shown below, which allows to reference methods and pass them as objects.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class MyExtension extends SFSExtension\r\n{\r\n    @Override\r\n    public void init()\r\n    {\r\n         \/\/ Add a new Request Handler\r\n        addRequestHandler(&quot;echo&quot;, this::handleEchoRequest);\r\n    }\r\n\r\n    private void handleEchoRequest(User sender, ISFSObject params)\r\n    {\r\n    \tsend(&quot;echo&quot;, resObj, sender);\r\n    }\r\n}\r\n<\/pre>\n<h3>Which style to use<\/h3>\n<p>Passing functions inline or via the double colon operator is very handy and the best option for short sections of code. However the &#8220;traditional&#8221; way of implementing a dedicated class per handler remains the recommended way to organize the server code.<\/p>\n<p>This is especially true when a request or event handler deals with a complex set of actions that span across multiple methods and depends on many other classes. In those cases being able to keep your handlers separated and organized is probably best and will help maintaining the code in the long run.<\/p>\n<p>The bottom line is that lambdas are an extra tool in our bag to use when it is appropriate and to get rid of unnecessary Java boilerplate code. You can not only integrate the functional aspects provided by the SFS2X server API, but also take advantage of it in the game logic.<\/p>\n<h3>Other resources<\/h3>\n<p>If you&#8217;re interested in learning more about functional Java we highly recommend a number of external articles:<\/p>\n<ul>\n<li><a href='https:\/\/en.wikipedia.org\/wiki\/Anonymous_function' target=\"_blank\">Wikipedia: Anonymous functions<\/a>\n<li><a href='https:\/\/docs.oracle.com\/javase\/tutorial\/java\/javaOO\/lambdaexpressions.html' target=\"_blank\">Oracle: Lambda expressions<\/a>\n<li><a href='https:\/\/www.ibm.com\/developerworks\/library\/j-java8idioms7\/index.html' target=\"_blank\">IBM: Functional interfaces<\/a>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>With the release of patch 2.13.1 SmartFoxServer 2X adds support for functional Java and lambdas in server side Extensions. In this article we&#8217;re going to take a closer look at how we can use lambdas in our server side code.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[31,91,12,90,7],"_links":{"self":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/813"}],"collection":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/comments?post=813"}],"version-history":[{"count":34,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/813\/revisions"}],"predecessor-version":[{"id":860,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/posts\/813\/revisions\/860"}],"wp:attachment":[{"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/media?parent=813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/categories?post=813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/smartfoxserver.com\/blog\/wp-json\/wp\/v2\/tags?post=813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}