<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div>Release inlining could be a compiler option only activated when desired. </div><div>It would require no additional semantics to the language, only the additional lantency associated with swapping inlined code times the number of modules, though we may be able to go sublinear here. </div><div><br>On 17 Feb 2016, at 06:53, Michael Truog <<a href="mailto:mjtruog@gmail.com">mjtruog@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div>
  
    <meta content="text/html; charset=windows-1252" http-equiv="Content-Type">
  
  
    <div class="moz-cite-prefix">On 02/15/2016 07:38 AM, Pierre Fenoll
      wrote:<br>
    </div>
    <blockquote cite="mid:CAMmfOZusrzkOhzBj03PALBq-yq_Jg3L8L5116=0PxKeb4oVEnQ@mail.gmail.com" type="cite">
      <div dir="ltr">This is surely a very naive idea on how to one day
        get cross-module inlining
        <div>or at least enlarge the range of possibilities for the JIT.
          <div><br>
          </div>
          <div>A lot of inlining is impossible due to the possibility to
            hot-swap code.</div>
          <div>But what about in the context of a release?</div>
        </div>
      </div>
    </blockquote>
    Inlining isn't impossible due to the possibility to hot-swap code. 
    However, inlining is simpler when modules are grouped together into
    a blob you can call a release.<br>
    <br>
    Inlining could rely on the inlined version of a function and a
    non-inlined version of the function where the inlined version of a
    function contains references to all the versions of various modules
    that it depends on.  Any hot-code loading should then create a
    ripple effect, changing the rest of the system in a way not limited
    to the module being updated, which makes the module update process
    error-prone (if only due to the difference in latency with a module
    being indirectly changed due to a function inline) when abandoning
    the concept of isolation.<br>
    <br>
    Tracking the dependencies that can be cyclic should be a complexity
    that is at least linear, so as you add more inlined functions, the
    latency with a module update grows in at least a linear way.  That
    means a module update could cause longer downtime due to a module
    update when many functions are inlined, where the downtime is worse
    as more functions get inlined, and that is only when considering the
    inlining in the old version of the module.  When inlining is used,
    you have the tendency to group modules together, as you have
    described, to try to make sure everything is inlined as a group, so
    you preserve the lower latency function calls.  If all the modules
    that are inlined together are updated together, you can minimize any
    problems dealing with non-inlined versions of the functions due to
    dependencies on old modules, but that would make the module update
    process longer, and would avoid the isolation a single module update
    currently provides.<br>
    <br>
    Forcing inlined modules to be updated in a big group might be nice
    with application versions, if you say functions can only be inlined
    within a single OTP application and not across OTP application
    boundaries, but as the documentation does show, changing an OTP
    application during runtime is ad-hoc since it depends on what you
    are doing to your supervisor(s) and everything else, while a single
    module update is a simple atomic change between two module versions.<br>
    <br>
    It is a really nice property of a module update, with the current
    situation in Erlang, where you know only the module will be changing
    when you update the source code.  Keeping that isolation of change
    to make sure potential errors have a definite and clear scope is
    important.  The problem of dealing with dependencies due to inlining
    is why I suggested using a templating concept instead, since that
    achieves inlining without making module updates error-prone.<br>
    <br>
    <blockquote cite="mid:CAMmfOZusrzkOhzBj03PALBq-yq_Jg3L8L5116=0PxKeb4oVEnQ@mail.gmail.com" type="cite">
      <div dir="ltr">
        <div>
          <div><br>
          </div>
          <div>When creating a release (or updating an old one),</div>
          <div>the compiler/relx/whatever is generating the release has
            a clear and finite scope</div>
        </div>
        <div>of all the code that will be shipped and run.</div>
        <div>Maybe not a clear idea of extra dependencies or resources,</div>
        <div>but at least all the Erlang code should be there.</div>
        <div>Then a compiler would be able to do supercompilation,
          agressive inlining, …</div>
        <div><br>
        </div>
        <div>I was thinking that we could then get a release that
          resembles an executable</div>
        <div>and if we can link external dependencies (OpenSSL, …)</div>
        <div>we would then have a somewhat standalone binary that kind
          of works like escripts.</div>
        <div><br>
        </div>
        <div>Is my reasoning right?</div>
        <div>Where am I on the scale from extremely naive all the way up
          to ROK?</div>
      </div>
      <div class="gmail_extra"><br clear="all">
        <div>
          <div class="gmail_signature">
            <div dir="ltr">
              <div>
                <div><br>
                </div>
                <div>Cheers,</div>
                <div>-- </div>
                <div>Pierre Fenoll</div>
              </div>
              <div><br>
              </div>
            </div>
          </div>
        </div>
        <br>
        <div class="gmail_quote">On 7 December 2015 at 05:45, Richard A.
          O'Keefe <span dir="ltr"><<a moz-do-not-send="true" href="mailto:ok@cs.otago.ac.nz" target="_blank">ok@cs.otago.ac.nz</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
              On 3/12/2015, at 8:11 pm, Michael Truog <<a moz-do-not-send="true" href="mailto:mjtruog@gmail.com">mjtruog@gmail.com</a>>
              wrote:<br>
              > If we had header files that were only allowed to
              contain functions and<br>
              > types that we called "template files" for lack of a
              better name<br>
              > (ideally, they would have their own export statements
              to help<br>
              > distinguish between private functions/types and the
              interface for modules<br>
              > to use)<br>
              > AND<br>
              > we had the include files (and template files)
              versioned within the beam<br>
              > output (to address the untracked dependency problem).<br>
              ><br>
              > Wouldn't that approach be preferable when compared<br>
              > to trying to manage the module dependency graph
              during a<br>
              > runtime code upgrades?  Why would the "template
              files" approach<br>
              > not be sufficient?<br>
              <br>
            </span>These are the differences I can see between 'template
            files'<br>
            and 'import_static modules'.<br>
            <br>
            (1) 'template files' would not be modules.<br>
                Having their own export directives would make them<br>
                modul*ar*, but they could not use 'fun M:F/A' to refer<br>
                to their own functions, having no M they could use.<br>
            <br>
                This does not seem like a good thing.<br>
            <br>
            (2) Headers can be nested.  If 'template files' were to be<br>
                like headers, this would create nested scopes for top<br>
                level functions, and the possibility of multiple<br>
                distinct functions with the same name and arity and<br>
                in some sense "in" the very same module.<br>
            <br>
                I don't see that as an insuperable problem, but it's a<br>
                very big change to the language in order to avoid what<br>
                is really not likely to be a practical problem.<br>
            <br>
            (3) 'template files' are copied into the including module,<br>
                which allows different modules to have included<br>
                different versions of a 'template file'.<br>
            <br>
                Like headers, this DOES NOT SOLVE the dependency and<br>
                version skew problems, IT CREATES THOSE PROBLEMS.<br>
            <br>
            So with 'template files', either you have precisely the<br>
            same problems you have with headers plus a whole lot of<br>
            extra complexity, or you have to track dependencies anyway.<br>
            <br>
            If we can take a step away from Erlang,<br>
            we can see that we have a fundamental problem.<br>
            <br>
            Resource A is prepared from foundations x and c.<br>
            Resource B is prepared from foundations y and c.<br>
            Resources A and B have to "fit together" in some fashion.<br>
            Common foundation c has something to do with how that<br>
            fitting together works.<br>
            <br>
            c is revised to c'.<br>
            A is re-prepared to A'.<br>
            If B were re-prepared, B' and A' would be compatible,<br>
            just as B and A were compatible.<br>
            But B and A' are not compatible.<br>
            <br>
            As far as I can see, there are three general ways to<br>
            deal with this kind of problem.<br>
            <br>
            1.  Detection.  When you try to use A' and B together,<br>
                detect that they were prepared from c' and c and<br>
                refuse to allow this use.<br>
            <br>
                This requires dependency tracking.<br>
            <br>
            2.  Prevention.  When c is revised to c', use dependencies<br>
                forward and queue A and B for rebuilding.<br>
            <br>
                This requires dependency tracking.<br>
            <br>
            3.  Avoidance.  Make the preparation step fairly trivial<br>
                so that whenever A (B) makes references to c, the<br>
                latest version of c is used.<br>
            <br>
                In programming language terms, this is not even lazy<br>
                evaluation, it's call-by-name.  It's the way Erlang<br>
                currently handles remote calls.  (More or less.)<br>
            <br>
                As a rule of thumb, early binding is the route to<br>
                efficiency (and early error detection), late binding<br>
                is the route to flexibility (and late error detection).<br>
                The performance cost may be anywhere between slight and<br>
                scary depending on the application.<br>
            <br>
            3'. It is only necessary to provide the *appearance* of late<br>
                binding.  I have a faint and probably unreliable memory<br>
                that the SPITBOL implementation of SNOBOL4 could
            generate<br>
                "optimised" code but could back it out and recompile it<br>
                when the assumptions it had made turned out to be wrong.<br>
            <br>
                Amongst other things, this requires the system to keep<br>
                track of this-depends-on-that at run time, so it's still<br>
                dependency tracking, but it need not be visible to the<br>
                programmer.<br>
            <br>
                What might be noticeable would be a performance blip as<br>
                loading c' caused everything that had been run-time
            compiled<br>
                against c to be de-optimised.  TANSTAAFL.<br>
            <div class="HOEnZb">
              <div class="h5"><br>
                <br>
                _______________________________________________<br>
                erlang-questions mailing list<br>
                <a moz-do-not-send="true" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
                <a moz-do-not-send="true" href="http://erlang.org/mailman/listinfo/erlang-questions" rel="noreferrer" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </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>
  

</div></blockquote></body></html>