{"id":1479,"date":"2018-03-14T14:06:32","date_gmt":"2018-03-14T14:06:32","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=1479"},"modified":"2021-10-08T11:05:10","modified_gmt":"2021-10-08T11:05:10","slug":"user-stories-funkwerk","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2018\/03\/14\/user-stories-funkwerk\/","title":{"rendered":"User Stories: Funkwerk"},"content":{"rendered":"<p>The deadline for the early-bird <a href=\"https:\/\/dlang.org\/blog\/2018\/01\/31\/dconf-2018-register-now\/\">registration for DConf 2018 in Munich<\/a> is coming up on March 17th. The price will go up from $340 to $400. If you\u2019d like to go, hurry and sign up to save yourself $60. And remember, the NH Munich Messe hotel, the conference venue, is offering <a href=\"https:\/\/dlang.org\/blog\/2018\/02\/23\/dconf-2018-munich-the-venue\/\">a special deal on single rooms plus breakfast<\/a> for attendees.<\/p>\n<hr \/>\n<p><img loading=\"lazy\" class=\"size-full alignleft\" src=\"https:\/\/i2.wp.com\/www.funkwerk.com\/wp-content\/themes\/funkwerk\/library\/images\/logo.png?resize=250%2C81\" width=\"250\" height=\"81\" \/><\/p>\n<p>A few of the DConf attendees are coming from <a href=\"http:\/\/www.funkwerk.com\">a local company called Funkwerk<\/a>. They\u2019re a D shop that we\u2019ve highlighted here on this blog in <a href=\"https:\/\/dlang.org\/blog\/d-in-production\/\">a series of posts<\/a> about their projects (you\u2019ll see <a href=\"https:\/\/dlang.org\/blog\/2017\/07\/28\/project-highlight-funkwerk\/\">one of their products in action<\/a> if you take the subway or local train service in Munich).<\/p>\n<p>In this post, we cap off the Funkwerk series with the launch of a new feature we creatively call \u201cUser Stories\u201d. Now and again, we\u2019ll publish a post in which D users talk of their experiences with D, not about specific projects, but about the language itself. They\u2019ll tell of things like their favorite features, why they use it, how it has changed the way they write code, or anything they\u2019d like to say that expresses how they feel about programming in D.<\/p>\n<p>For this inaugural post, we\u2019ve got three programmers from Funkwerk. First up, Michael Schnelle talks about the power of ranges. Next, Ronny Spiegel tells why generated code is better code. Finally, Stefan Rohe enlightens us on Funkwerk\u2019s community outreach.<\/p>\n<h2 id=\"thepowerofranges\">The power of ranges<\/h2>\n<p><em>Michael Schnelle has been working as a software developer for about 5 years. Before starting with D 3 years ago, he worked in (Web)Application Development, mostly with Java, Ruby on Rails, and C++, and did Thread Modeling for Applications. He enjoys coding in D and likes how it helps programmers write clean code.<\/em><\/p>\n<p>In my experience, no matter what I am programming, I always end up applying functions to a set of data and filter this set of data. Occasionally I also execute something with side effects in between. Let\u2019s look at a simplified use case: the transformation of a given set of data and filtering for a condition afterwards. I could simply write:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">foreach(element; elements) {\r\n  auto transformed = transform(element);\r\n  if (metCondition(transformed) {\r\n     results ~= transformed\r\n  } \r\n}<\/pre>\n<p>Using the power from <a href=\"https:\/\/dlang.org\/phobos\/std_algorithm.html\"><code>std.algorithm<\/code><\/a>, I can instead write:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">filter!(element =&gt; metCondition(element))\r\n       (map!(element =&gt; transform(element))(elements));<\/pre>\n<p>At this point, we have a mixture of functional and object-oriented code, which is quite nice, but still not quite as readable or easy to understand as it could be. Let\u2019s combine it with <a href=\"https:\/\/tour.dlang.org\/tour\/en\/gems\/uniform-function-call-syntax-ufcs\">UFCS (Uniform Function Call Syntax)<\/a>:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">elements.map!(element =&gt; element.transform)\r\n        .filter!(element =&gt; element.metCondition);<\/pre>\n<p>I really like this kind of code, because it is clearly self-explanatory. The <code>foreach<\/code> loop, on the other hand, only tells me how it is being done. If I look through our code at Funkwerk, it is almost impossible to find traditional loops.<\/p>\n<p>But this only takes you one step further. In many cases, there happen to be side effects which need to be executed during the workflow of the program. For this kind of thing, the library provides functions like <a href=\"https:\/\/dlang.org\/phobos\/std_range.html#tee\"><code>std.range.tee<\/code><\/a>. Let\u2019s say I want to execute something external with the transformed value before filtering:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">elements\r\n  .map!(element =&gt; element.transform)\r\n  .tee!(element =&gt; operation(element))\r\n  .filter!(element =&gt; element.metCondition)\r\n  .array;<\/pre>\n<p>It is crucial that operations with side effects are only executed with higher-order functions that are built for that purpose.<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">int square(int a) { writefln(\"square value\"); return a*a; }\r\n\r\n[4, 5, 8]\r\n  .map!(a =&gt; square(a))\r\n  .tee!(a =&gt; writeln(a))\r\n  .array;<\/pre>\n<p>The code above would print out the square value six times, because <code>tee<\/code> calls <code>range.front<\/code> twice. It is possible to avoid this by using functions like <a href=\"https:\/\/dlang.org\/phobos\/std_algorithm_iteration.html#.cache\"><code>std.algorithm.iteration.cache<\/code><\/a>, but in my opinion, the nice way would be to avoid side effects in functions that are not meant for that.<\/p>\n<p>In the end, D gives you the possibility to combine the advantages of object-oriented and functional programming, resulting in more readable and maintainable code.<\/p>\n<h2 id=\"generatedcodeisbettercode\">Generated code is better code<\/h2>\n<p><em>Ronny Spiegel has worked as a professional software developer for almost 20 years. He started out using C and C++, but when he joined Funkwerk he really started to love the D language and the tools it provides to introspect code and to automate things at compile time.<\/em><\/p>\n<p>In <a href=\"https:\/\/dlang.org\/blog\/2017\/09\/06\/the-evolution-of-the-accessors-library\/\">a previous blog post<\/a>, I gave a short overview of the evolution of the accessors library. As you might imagine, I really like the idea of using the compiler to generate code; in the end this usually results in less work for me and, as a direct result, causes fewer errors.<\/p>\n<p>The establishment of coding guidelines is crucial for a team in order to create maintainable software, and so we have them here at Funkwerk. There is a rule that every value object (or entity) has to implement the <code>toString<\/code> method in order to provide diagnostic output. The provided string shall be unambiguous so that it\u2019s more like Python\u2019s <code>__repr__<\/code> than <code>__str__<\/code>.<\/p>\n<p>Example:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">StationMessage(GeneralMessage(4711, 2017-12-12T10:00:00Z), station=\"BAR\", \u2026)<\/pre>\n<p>The generated string should follow some conventions:<\/p>\n<ul>\n<li>provide a way to uniquely reconstruct data from a string\n<ul>\n<li>start with the class name<\/li>\n<li>continue with any potential superclasses<\/li>\n<li>list all fields providing their name and value separated by a comma<\/li>\n<\/ul>\n<\/li>\n<li>be compact but still human readable (for developers)\n<ul>\n<li>skip the name where it matches the type (e.g. a field of type <code>SysTime<\/code> is called <code>time<\/code>)<\/li>\n<li>skip the name if the field is called <code>id<\/code> (usually there\u2019s an <code>IdType<\/code> used for type safety)<\/li>\n<li>there\u2019s some special output format defined for types like <code>Date<\/code> and <code>SysTime<\/code><\/li>\n<li><code>Nullable!T<\/code>\u2019s will be skipped if <code>null<\/code> etc.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>To format output in a consistent manner, we implemented a <code>SinkWriter<\/code> wrapping <code>formattedWrite<\/code> in a way that follows the listed conventions. If this <code>SinkWriter<\/code> is used everywhere, this is the first step to fully generate the <code>toString<\/code> method.<\/p>\n<p>Unfortunately that\u2019s not enough; it\u2019s very common to forget something when adding a new field to a class. Today I stumbled across some code where a field was missing in the diagnostics output and that led to some confusion.<\/p>\n<p>Using <a href=\"https:\/\/dlang.org\/spec\/template-mixin.html\">(template) mixins<\/a> together with <a href=\"https:\/\/dlang.org\/spec\/function.html#interpretation\">CTFE (Compile Time Function Execution)<\/a> and the provided type traits, D provides a powerful toolset which enables us to generate such functions automatically.<\/p>\n<p>We usually implement an alternative <code>toString<\/code> method which uses a sink delegate as described in <a href=\"https:\/\/wiki.dlang.org\/Defining_custom_print_format_specifiers\">https:\/\/wiki.dlang.org\/Defining_custom_print_format_specifiers<\/a>. The implementation is a no-brainer and looks like this:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">public void toString(scope void delegate(const(char)[]) sink) const\r\n{\r\n    alias MySelf = Unqual!(typeof(this));\r\n\r\n    sink(MySelf.stringof);\r\n    sink(\"(\");\r\n\r\n    with (SinkWriter(sink))\r\n    {\r\n        write(\"%s\", this.id_);\r\n        write(\"station=%s\", this.station_);\r\n        \/\/ ...\r\n    }\r\n\r\n    sink(\")\");\r\n}<\/pre>\n<p>This code seems to be so easy that it might be generalized like this:<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">public void toString(scope void delegate(const(char)[]) sink) const\r\n{\r\n    import std.traits : FieldNameTuple, Unqual;\r\n\r\n    alias MySelf = Unqual!(typeof(this));\r\n\r\n    sink(MySelf.stringof);\r\n    sink(\"(\");\r\n\r\n    with (SinkWriter(sink))\r\n    {\r\n        static foreach (fieldName; FieldNameTuple!MySelf)\r\n        {{\r\n            mixin(\"const value = this.\" ~ fieldName ~ \";\");\r\n            write!\"%s=%s\"(fieldName, value);\r\n        }}\r\n    }\r\n\r\n    sink(\")\");\r\n}<\/pre>\n<p>The above is just a rough sketch of how such a generic function might look. For a class to use this generation approach, simply call something like<\/p>\n<pre class=\"prettyprint lang-d\" data-caption=\"\" data-highlight=\"\" data-visibility=\"visible\" data-start-line=\"1\">mixin(GenerateToString);<\/pre>\n<p>inside the class declaration, and that\u2019s it. Never again will a field be missing in the class\u2019s <code>toString<\/code> output.<\/p>\n<p>Generating the <code>toString<\/code> method automatically might also help us to switch from the common <code>toString<\/code> method to an alternative implementation. If there will be more conventions over time, we will only have to extend the <code>SinkWriter<\/code> and\/or the <code>toString<\/code>-template, and that\u2019s it.<\/p>\n<p>As a summary: <strong>Try to generate code if possible &#8211; it is less error prone and D supports you with a great set of tools!<\/strong><\/p>\n<h2 id=\"funkwerkandthed-community\">Funkwerk and the D-Community<\/h2>\n<p><em><a href=\"https:\/\/github.com\/lindt\">Stefan Rohe<\/a> started the D-train at Funkwerk back in 2008. They have loved DLang since then and replaced D1-Tango with D2-Phobos in 2013. They are strong believers in <a href=\"https:\/\/github.com\/funkwerk\">open source<\/a> and <a href=\"https:\/\/www.meetup.com\/de-DE\/Munich-D-Programmers\/\">local communities<\/a>, and are thrilled to see you all in Munich at <a href=\"http:\/\/dconf.org\/2018\/index.html\">DConf 2018<\/a>.<\/em><\/p>\n<p>Funkwerk is the largest D shop in south Germany, so we hire <em>D-velopers<\/em>, mainly just through being known for programming in D. In order to give a little bit back to the D community at large and help the local community grow, Funkwerk hosted the foundational edition of the <a href=\"https:\/\/www.meetup.com\/de-DE\/Munich-D-Programmers\/\">Munich D Meetup<\/a>.<\/p>\n<h3 id=\"thelocalcommunityisimportant...\">The local community is important \u2026<\/h3>\n<p><img loading=\"lazy\" class=\"alignright\" src=\"http:\/\/dlang.org\/blog\/wp-content\/uploads\/2018\/03\/Brainlab.png\" alt=\"Munich Meetup at Brainlab\" width=\"449\" height=\"299\" \/><\/p>\n<p>The meetup was founded in August 2016, 8 years after the first line of D code at Funkwerk was written. Since then, the Meetup has grown steadily to ~350 members. At that number, it is still not the biggest D Meetup, but it is the most visited and the most active. It provides a chance for locals in Munich to interact with like-minded D-interested people each month. And with an alternating level of detail and a different location each month, it stays interesting and attracts different participants.<\/p>\n<h3 id=\"\u2026andsoistheglobalcommunity\">\u2026 and so is the global community<\/h3>\n<p>To engage with the global community, Funkwerk is willing to open source some of its general-purpose D libraries. They can all be found under <a href=\"https:\/\/github.com\/funkwerk\">github.com\/funkwerk<\/a>, and some are registered in <a href=\"https:\/\/code.dlang.org\/\">the DUB registry<\/a>.<\/p>\n<p>To mention are:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/funkwerk\/accessors\">accessors<\/a> &#8211; a library to auto generate getters and setters with UDAs<\/li>\n<li><a href=\"https:\/\/github.com\/funkwerk\/depend\">depend<\/a> &#8211; a tool that checks actual import dependencies against a UML model of target dependencies<\/li>\n<li><a href=\"https:\/\/github.com\/funkwerk\/d2uml\">d2uml<\/a> &#8211; reverse engineering of D source code into PlantUML class outlines<\/li>\n<\/ul>\n<p>Feel free to use these and let us know how you like them.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, we cap off the Funkwerk series with the launch of a new feature we creatively call \u201cUser Stories\u201d. Now and again, we\u2019ll publish a post in which D users talk of their experiences with D, not about specific projects, but about the language itself. They\u2019ll tell of things like their favorite features, why they use it, how it has changed the way they write code, or anything they\u2019d like to say that expresses how they feel about programming in D.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,15,28,9,34],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1479"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=1479"}],"version-history":[{"count":9,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1479\/revisions"}],"predecessor-version":[{"id":1492,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1479\/revisions\/1492"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=1479"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=1479"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=1479"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}