<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    I really, really want to recommend option 5: not using parametrized
    modules.<br>
    <br>
    Dialyzer is the first of your concerns. Next up, you'll be having
    trouble with code tracing, which is also messed up due to the arity
    issues. Then what about function guards?<br>
    <br>
    There are a few valid use cases for parametrized modules, and
    Richard Carlsson can demonstrate them well, but I would generally
    advise against it (a lot of it is personal preferences, I got to
    admit). Shadowing, messed up arities, different semantics, etc. all
    annoy me a bit.<br>
    <br>
    Here's a quick list of the problems, based on the following module:<br>
    <br>
    <blockquote><tt>-module(pmo</tt><tt>d,[Arg]).<br>
        -compile(export_all).<br>
        f() -> Arg.<br>
      </tt></blockquote>
    Using it in a shell started as:<br>
    <blockquote><tt>1> c(pmod).</tt><br>
      <tt>{ok,pmod}</tt><br>
      <tt>2> M = pmod:new(hello).</tt><br>
      <tt>{pmod,hello}</tt><br>
    </blockquote>
    1. function building is broken:<br>
    <blockquote><tt>3> fun M:f/0.                            <br>
        ** exception error: bad argument<br>
             in function  erlang:make_fun/3<br>
                called as erlang:make_fun({pmod,hello},f,0)</tt><br>
    </blockquote>
    You can't get the above to work without either forgetting about
    parametrized modules (passing the argument to the function) or
    wrapping it in an anonymous function as <tt>fun() -> M:f() end</tt>,
    although this one has the problem of potentially being purged during
    code reload, which a proper pmod anonymous function wouldn't.<br>
    <br>
    2. Tracing is broken due to changes in arity:<br>
    <blockquote><tt>4> dbg:tp({M, f, 0}, []).<br>
        ** exception error: no case clause matching {pmod,hello}<br>
             in function  dbg:do_tp/3 (dbg.erl, line 141)<br>
        5> dbg:tp({pmod, f, 0}, []).<br>
        {ok,[]}<br>
        6> dbg:tp({pmod, f, 1}, []).<br>
        {ok,[]}<br>
      </tt></blockquote>
    The first one plainly doesn't work, the second one will never match
    anything, and the third one is actually the valid one.<br>
    <br>
    3. Tricky pattern matching.<br>
    If I add the following function definition to the pmod module:<br>
    <blockquote><tt>id(Arg) -> Arg.</tt><br>
    </blockquote>
    And then try to use it, see what can happen:<tt><br>
    </tt>
    <blockquote><tt>7> c(pmod).</tt><br>
      <tt>{ok,pmod}</tt><br>
      <tt>8> pmod:id(4).</tt><br>
      <tt>** exception error: undefined function pmod:id/1</tt><br>
      <tt>9> M:id(4).            </tt><br>
      <tt>** exception error: no function clause matching
        pmod:id(4,{pmod,hello}) (pmod.erl, line 6)</tt><br>
      <tt>10> M:id(hello).</tt><br>
      <tt>hello</tt><br>
    </blockquote>
    The way you name the variable will impact pattern matching. Although
    it <b>is</b> likely the best behaviour available, it is weird to
    have this behaviour happening, you need to watch yourself. This kind
    of stuff won't happen if you use pmods with great care, but I'm a
    pessimist on these questions.<br>
    <br>
    Related to this, this isn't the most intuitive kind of error to
    debug in the middle of a larger file. If you add:<br>
    <blockquote><tt>y() -> fun(Arg) -> Arg end.<br>
      </tt></blockquote>
    You get compiler warnings telling you <i>pmod.erl:8: Warning:
      variable 'Arg' shadowed in 'fun'</i>, still a scoping issue for
    the distracted programmer. Imagine using the same variable in a <tt>case
      ... of</tt> match without thinking of it. Some programmers get it
    wrong with the normal scoping rules, nevermind with parametrized
    arguments on top of it.<br>
    <br>
    4. They don't work well with tools like Dialyzer, as you found out.<br>
    <br>
    Those are the ones I got from the top of my head. I know people will
    defend Parametrized modules, that they have valid use cases (I can
    admit to a few!), that a lot of these issues are implementation
    details that can be fixed, but as of now, they aren't, and they mess
    stuff up.<br>
    <br>
    Sorry, I know this isn't the kind of answer you want to such a
    question.<br>
    <br>
    <div class="moz-cite-prefix">On 12-08-14 4:41 AM, VegaS wrote:<br>
    </div>
    <blockquote
cite="mid:CAPMh89AkavyPKjiREvqV2a=-fA8tXSYwa_nyLVVfSTmYm+6esg@mail.gmail.com"
      type="cite">Hello all!
      <div><br>
      </div>
      <div>We are using parametric modules in our project and were quite
        happy with them unless we have started using Dialyzer.</div>
      <div>Dialyzer fails on parametric modules because functions in
        parametric modules are expanded with module params argument on
        compilation stage - so function's specs are unmatched.</div>
      <div><br>
      </div>
      <div>I know that parametric modules not the official part of
        Erlang, but I'd like to get both parametric modules and dialyzer
        working. I have tried to do some work on this:</div>
      <div>1. Try to fix specs on parametric module's functions with
        parse_transform - simply extend specs on this stage, but this
        won't work, code just won't compile (because of specs for
        unknown functions)</div>
      <div>2. More complicated approach - try to implement parametric
        modules with parse_transform (create "new" function and extend
        all module functions and specs). This looks working unless some
        code like</div>
      <div>
             SomeFun = local_fun/1, SomeFun(Arg) and some variations
        like this local function is assigned to record field.</div>
      <div>3. Decided that there no way out besides patching OTP sources
        or not using parametric modules at all. After looking at OTP
        sources I have found, that parametric modules are expanded on on
        "<span
          style="line-height:16px;color:rgb(51,51,51);font-size:12px;white-space:pre-wrap;font-family:Consolas,'Liberation
          Mono',Courier,monospace">expand_module</span>" compiler pass.
        And on that stage specs are not expanded. I Have patched this
        stage with specs expand. All were correct, but dialyzer fails
        with message like specs were not fixed, so no luck... This
        happend because dialyzer using "abstract_code" from beam to
        extract specs and pass "<span
          style="line-height:16px;color:rgb(51,51,51);font-size:12px;white-space:pre-wrap;font-family:Consolas,'Liberation
          Mono',Courier,monospace">save_abstract_code</span>" is just
        before "<span
          style="line-height:16px;color:rgb(51,51,51);font-size:12px;white-space:pre-wrap;font-family:Consolas,'Liberation
          Mono',Courier,monospace">expand_module</span>" pass.</div>
      <div>Simple changing these passes order broke dialyzer at all.</div>
      <div>4. The last attempt were to patch dialyzer - on the stage,
        when it extracts specs info from beam's abstract_code section.
        At this place I insert function's specs expanding with last
        parametric parameter - and it works!</div>
      <div><br>
      </div>
      <div>So the question is what the rigth way to make both parametric
        modules and dialyzer working?</div>
      <div>At my opinion there are no way except OTP sources patching -
        but what the rigth place for making such patch? </div>
      <div><br>
      </div>
      <div>I can attach my patch here but it is little ugly (I were
        tired by previous explorations) and I think I have chosen not
        rigth place for changing.</div>
      <div> </div>
      <div><br>
      </div>
      <div>Thanks,</div>
      <div>
        Lihanov Alexandr</div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>