<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    <br>
    On 23/3/12 3:35 , Robert Virding wrote:
    <blockquote cite="mid:7e02f8de-2680-49d1-8293-1d14a96f57d8@knuth"
      type="cite">
      <style type="text/css">p { margin: 0; }</style>
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);">Got in late here but some comments:<br>
        <br>
        - I feel it is very important to separate client- and server
        side. I give quite a few courses and this concept can be
        difficult for many people. Especially those who come from the OO
        side who view modules as classes. So anything which hides this
        is bad. Yes, I know that they will learn but why make it more
        difficult. Also I like things to be explicit.<br>
      </div>
    </blockquote>
    After hearing the arguments I am in agreement with this split.<br>
    <blockquote cite="mid:7e02f8de-2680-49d1-8293-1d14a96f57d8@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);"><br>
        - I personally don't really see the problem here, but then I am
        old school. Much of the boiler plate code is very short so
        specifying it for a "tool" will actually not save much typing, I
        still have to give the details and the code to be run in the
        server.<br>
      </div>
    </blockquote>
    For me the biggest annoyance is that in most cases the code in your
    API function simply wraps the incoming arguments with some tag and
    that tag has to be matched with a clause in the handle_call
    function. <br>
    As far as I can see there is no way to enforce a match unless you
    start creating records for each message you want to send to the
    internal server... hmmm, maybe that is not so bad after all... I
    will toy a bit with that thought.<br>
    <br>
    There is a bit of flexibility in the e2project since you do not have
    to write one big handle_call function - you may choose to have
    several handle_*  functions. It is a bit clearer, but there is no
    enforcement since the function you specify as handler is dispatched
    through the e2_service:call/2 function. <br>
    Looking at this again there seems to be no easy fix to this "hole"
    since there is a dispatching involved here. The only thing that
    gives you some warning is to start using records for the messages,
    but it seems at bit dramatic to do that.<br>
    Putting specs on the internal protocol will not help due to the
    dispatching.<br>
    <br>
    <blockquote cite="mid:7e02f8de-2680-49d1-8293-1d14a96f57d8@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        rgb(0, 0, 0);"><br>
        My personal (biased) opinion is that has more to do with what
        they are used to rather than usefulness.<br>
      </div>
    </blockquote>
    There is definitely some of that in this equation.<br>
    <br>
    Cheers,<br>
    Torben<br>
    <blockquote cite="mid:7e02f8de-2680-49d1-8293-1d14a96f57d8@knuth"
      type="cite">
      <div style="font-family: Times New Roman; font-size: 12pt; color:
        #000000"><br>
        Robert<br>
        <br>
        <hr id="zwchr">
        <blockquote style="border-left:2px solid rgb(16, 16,
255);margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
          As OP I take the liberty to do a top post and try to summarise
          a few things at this point.<br>
          <br>
          I am not alone when it comes to having an urge to remove some
          of the boilerplate code. I guess we all want value for our
          money and when we have to do something that does not provide
          that we want to improve. If we did not have that craving we
          might as well be coding enterprise Java applications using
          dozens of frameworks ;-)<br>
          <br>
          I had a look at the e2project and it actually does remove some
          of the boilerplate that I find the most iritating, namely the
          tagging of messages from the API function to the handle_*
          function. It is a lot clearer in e2project where you reference
          a function in the e2_service:call - I like that a lot.<br>
          <br>
          The approach with parse transforms has its merits, but I think
          that the e2project can do away with most of the pains I have
          been feeling, so I think I will leave out the semi-black magic
          of parse transforms for now... it is a tool that should be
          used with caution as other posters have mentioned.<br>
          <br>
          The IDL approach I had in mind was nothing about CORBA - I
          should never have mentioned CORBA in my original mail, there
          are too many negative feelings associated to CORBA. <br>
          What I like about IDLs is that it allows you to spec your API
          in a nice way and in many cases it will be possible to avoid
          writing boilerplate code (either through code generation or
          using a parse transform).<br>
          <br>
          Given the good point made about separating the client and the
          server side of things I think that what is needed is simply to
          spec up the API function (who doesn't do that already?!?!) and
          then try out e2project. The spec will give me a slap over my
          fingers if I do not provide the function (I like that) and
          e2project seems to minimise the tedious boilerplate stuff from
          standard gen_server without limiting my ability to express
          what I need.<br>
          <br>
          A big thanks to all posters - I am glad I asked the question!<br>
          <br>
          Cheers,<br>
          Torben<br>
          <br>
          On 21/3/12 21:10 , Tim Watson wrote:
          <blockquote
            cite="mid:6F99D60B-C45A-4E21-AAEC-FF5E1630298E@gmail.com">
            <div>
              <div>On 21 Mar 2012, at 19:22, Garrett Smith wrote:</div>
              <blockquote>
                <div>
                  <blockquote><font class="Apple-style-span"
                      color="#000000"><br>
                    </font></blockquote>
                  <br>
                  This may come down to personal taste. I don't like
                  having to dig<br>
                  around in parse transform code to understand what my
                  module looks<br>
                  like.<br>
                  <br>
                </div>
              </blockquote>
              <div><br>
              </div>
              <div>Neither do I - that's why I simply run 'escript `evm
                site`/parse_trans/ebin/parse_trans_pp.beam
                ebin/<target>.beam' over the generated beam to see
                what it looks like at source level. ;)  </div>
              <br>
              <blockquote>
                <div>eunit is a great example. If you really love eunit,
                  then I'm not going<br>
                  to convince you :)<br>
                  <br>
                </div>
              </blockquote>
              <div><br>
              </div>
              <div>Common test and PropEr do exactly the same thing. I'm
                not sure what you're expected testing frameworks to do
                instead!?</div>
              <br>
              <blockquote>
                <div>
                  <blockquote>
                    <blockquote>- Hiding the client-server distinction
                      in Erlang is a terrible disservice<br>
                    </blockquote>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>I agree with this wholeheartedly, but
                    don't see what it has to do with code generation.<br>
                  </blockquote>
                  <br>
                  If you consolidate both the client and server
                  functions into one<br>
                  function, you've obfuscated an important distinction.<br>
                  <br>
                </div>
              </blockquote>
              <div><br>
              </div>
              <div>I never suggested doing that at all. Not that I mean
                to be prickly, as we're all part of the same community
                and whatnot, but nobody suggested separating both
                functions. What the OP suggested was that you could
                define the interface declaratively - e.g., without
                writing the code directly - and that was what I was
                responding to. As I mentioned later on, in this
                particular gen_server case I actually think your
                approach is probably cleaner and more appropriate, but
                it's good to separate these points and refine the
                discussion I think.</div>
              <br>
              <blockquote>
                <div>
                  <blockquote>
                    <blockquote>IMO, e2 solves the problem of "too much
                      boiler plate". It's really<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>easy and requires zero magic.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>Here's a "gen_server" equivalent in e2:<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><a moz-do-not-send="true"
href="https://github.com/gar1t/e2v2/blob/master/examples/ping/src/ping_server.erl"
                        target="_blank">https://github.com/gar1t/e2v2/blob/master/examples/ping/src/ping_server.erl</a><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>This is pretty cool though. :)<br>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>
                    <blockquote>You might object to the separation of
                      "ping" and "handle_msg" -- it<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>appears to be just one function, so why
                      break it up into two pieces?<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>The problem is that it's not one
                      function -- it's definitely *two*<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>very separate pieces of code.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>Absolutely and a good point!<br>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>When you write a gen_server style
                      module, you're writing code that<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>support client-server interactions. You
                      have, in the same module, code<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>that is called by the "client" and code
                      that is called by the<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>"server". If you don't grok this, you're
                      missing the entire point of<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>this type of module.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>Code that hides this difference -- e.g.
                      a parse transform that gloms<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>the client and server functions into one
                      -- is IMO a Really Bad Idea.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote><br>
                  </blockquote>
                  <blockquote>I don't necessarily agree with this, as
                    the parse transform can be applied to a -spec which
                    is potentially as intention revealing as a hand
                    written function. I do take your point about them
                    being two separate functions and perhaps in this
                    particular case (for gen_server) you are actually
                    correct and having two hand coded parts is actually
                    better. I don't buy 'code-gen is bad' as a general
                    argument (which perhaps you weren't going so far as
                    to make anyway), and I do see your point in this
                    instance.<br>
                  </blockquote>
                  <br>
                  I'm certainly not arguing against code generation. I
                  think Erlang's<br>
                  parse transform scheme is *very* good -- flexible
                  enough to enable<br>
                  elegant solutions but with enough complexity to scare
                  off casual "meta<br>
                  programmers".<br>
                  <br>
                  But -- I think there should be a very clear payoff for
                  using a parse<br>
                  transform. I don't think the discussion here, which is
                  "boilerplate"<br>
                  is a good application for that.<br>
                  <br>
                </div>
              </blockquote>
              <div><br>
              </div>
              <div>I think it depends on how much boilerplate you're
                looking at. As an OCaml programmer I have seen a *lot*
                of work going into removing boilerplate code, and the
                same in Haskell (although there I am less experienced)
                and overall I think the payoff you're describing is a
                value judgement based on the negative impact of using
                code generation. Generated code is brittle - there's no
                two ways about it. But it doesn't prevent you from
                testing or documenting, nor does it have to make your
                code opaque and difficult to understand, so long as it
                is not overused - a sprinkle here and there rather than
                a bucket load.</div>
              <br>
              <blockquote>
                <div>A good example of a value-add parse transform IMO
                  is modlib, which<br>
                  lets you create mods for inets httpd withou causing
                  your brain to<br>
                  explode [1].<br>
                  <br>
                  <blockquote>
                    <blockquote>As an example of how this client/server
                      difference is important,<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>consider form validation in a web app.
                      There are two places you can<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>run code to validate form input -- you
                      can validate it in the browser<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>using JavaScript, or you can send the
                      form data to the server. Web<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>developers may opt for browser
                      validation to avoid the expense of<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>sending data to the server -- or they
                      might prefer it on the server.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>Either way, it's an important
                      consideration.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>This same dynamic applies to gen_server
                      style modules. If you stick<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>with it, I think you'll appreciate the
                      separateness of client and<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>server facing code.<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>As for the boilerplate, I couldn't agree
                      with you more!<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>Garrett<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote><br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>P.S. I'm giving a talk on e2 at the SF
                      Factory in a couple weeks,<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>where I'll get into this in more
                      details. Also, the e2 docs and github<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>project are in slight disarray at the
                      moment, but will be put in order<br>
                    </blockquote>
                  </blockquote>
                  <blockquote>
                    <blockquote>this weekend!<br>
                    </blockquote>
                  </blockquote>
                  <br>
                  [1] <a moz-do-not-send="true"
                    href="https://github.com/gar1t/modlib"
                    target="_blank">https://github.com/gar1t/modlib</a><br>
                </div>
              </blockquote>
            </div>
            <br>
          </blockquote>
          <br>
          <pre class="moz-signature">--
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://www.linkedin.com/in/torbenhoffmann" target="_blank">http://www.linkedin.com/in/torbenhoffmann</a></pre>
          <br>
          _______________________________________________<br>
          erlang-questions mailing list<br>
          <a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
          <a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
        </blockquote>
        <br>
      </div>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
<a class="moz-txt-link-freetext" href="http://www.linkedin.com/in/torbenhoffmann">http://www.linkedin.com/in/torbenhoffmann</a></pre>
  </body>
</html>