<html><head><style type='text/css'>p { margin: 0; }</style></head><body><div style='font-family: Times New Roman; font-size: 12pt; color: #000000'>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><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><br>My personal (biased) opinion is that has more to do with what they are used to rather than usefulness.<br><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 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 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 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>erlang-questions@erlang.org<br>http://erlang.org/mailman/listinfo/erlang-questions<br></blockquote><br></div></body></html>