<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    It does seem like rustdoc could be extended to do something
    approximating literate programming without much hassle. I'd like to
    see this project built out-of-tree using the rustdoc and rustc
    API's.<br>
    <br>
    <div class="moz-cite-prefix">On 06/29/2014 12:38 PM, Evan G wrote:<br>
    </div>
    <blockquote
cite="mid:CAJY4u8FJCnyzGwxBHpDQt9Vi1fgLUPO-mYsKhV0uvf3vNxEuRg@mail.gmail.com"
      type="cite">
      <div dir="ltr">I'm not sure if this is exactly what you're looking
        for, but rust already has support for running code examples in
        documentation. If I remember correctly, all of the code examples
        in the guide are currently run and tested as part of make test,
        so this is at least part way towards what you want.<br>
        <div class="gmail_extra"><br>
          <br>
          <div class="gmail_quote">On Sun, Jun 29, 2014 at 2:30 PM,
            Nathan Typanski <span dir="ltr"><<a
                moz-do-not-send="true" href="mailto:ntypanski@gmail.com"
                target="_blank">ntypanski@gmail.com</a>></span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">Literate
              Rust (.lrs)<br>
              ====================<br>
              <br>
              I'm wondering if anyone else here has had the thought of
              supporting<br>
              literate programming in Rust. For those who don't know
              what this is<br>
              about, a language with good support for the concept is
              Haskell [1],<br>
              which normally uses bird-style (>) for code blocks. I
              would propose a<br>
              file extension (.lrs, most likely) that's dedicated to
              literate<br>
              usage.<br>
              <br>
              If there's some decent feedback for this, and people seem
              to enjoy it,<br>
              then I will do more research and write a RFC.<br>
              <br>
              [1]: <<a moz-do-not-send="true"
                href="http://www.haskell.org/haskellwiki/Literate_programming"
                target="_blank">http://www.haskell.org/haskellwiki/Literate_programming</a>><br>
              <br>
              ## Who would benefit from this<br>
              <br>
              ### Schools teaching Rust<br>
              <br>
              Universities teaching Rust would be one of my first bets
              as a user for<br>
              Literate Rust. While literate programming is sometimes too
              far a<br>
              stretch from reality for production code (which is both a
              good and bad<br>
              thing), pedagogical gains for literate programming are
              huge - you can<br>
              run the same code that's teaching you about the language
              or the<br>
              concept. Essays and writings that feature the code are<br>
              indistinguishable from valid Rust code.<br>
              <br>
              ### Documentation/books/etc.<br>
              <br>
              Another use is general documentation, books about Rust,
              etc. where<br>
              there are real benefits to having valid code all the way
              through them.<br>
              When walking through a sample project, the sample project
              is also the<br>
              code that produced it. This makes documentation easier,
              since you're<br>
              more able to ensure that your examples compile properly
              and actually<br>
              run when the compiler updates, etc.<br>
              <br>
              There's also a mental shift when doing literate
              programming, versus<br>
              just ///'ing within code and whatnot: your primary thought
              process<br>
              becomes thinking and communicating with the reader, rather
              than<br>
              working on the code. You focus more on the text and
              ensuring that it<br>
              makes sense.<br>
              <br>
              ## How this could work with Rustdoc for APIs<br>
              <br>
              API documentation in a literate program would be included
              as before,<br>
              in rustdoc comments in the output. The internal comments
              should be the<br>
              default for text, not external API.<br>
              <br>
              As an example, here's some code taken from<br>
              src/libstd/collections/<a moz-do-not-send="true"
                href="http://hashmap.rs" target="_blank">hashmap.rs</a>,
              and interpreted in a literate style:<br>
              <br>
                  > /// Does not initialize the buckets. The caller
              should ensure they,<br>
                  > /// at the very least, set every hash to
              EMPTY_BUCKET.<br>
                  > unsafe fn new_uninitialized(capacity: uint) ->
              RawTable<K, V> {<br>
                  >     let hashes_size =
              capacity.checked_mul(&size_of::<u64>())<br>
                  >                               .expect("capacity
              overflow");<br>
                  >     let keys_size =
              capacity.checked_mul(&size_of::< K >())<br>
                  >                             .expect("capacity
              overflow");<br>
                  >     let vals_size =
              capacity.checked_mul(&size_of::< V >())<br>
                  >                             .expect("capacity
              overflow");<br>
                  ><br>
              <br>
                  Allocating hashmaps is a little tricky. We need to
              allocate three<br>
                  arrays, but since we know their sizes and alignments
              up front,<br>
                  we just allocate a single array, and then have the
              subarrays<br>
                  point into it.<br>
              <br>
                  This is great in theory, but in practice getting the
              alignment<br>
                  right is a little subtle. Therefore, calculating
              offsets has been<br>
                  factored out into a different function.<br>
              <br>
                  >     let (malloc_alignment, hash_offset,
              keys_offset, vals_offset, size) =<br>
                  >         calculate_offsets(<br>
                  >             hashes_size,
              min_align_of::<u64>(),<br>
                  >             keys_size,   min_align_of::< K
              >(),<br>
                  >             vals_size,   min_align_of::< V
              >());<br>
              <br>
              The non-bird text (without the >) is what would
              normally go in the<br>
              comments for the code. In this case, since it's an API,
              the thing you<br>
              actually want in your regular documentation is still the
              rustdoc api<br>
              comments (///), but with the option of generating a
              literate<br>
              presentation of the code (perhaps by autoconversion to
              pandoc?) where<br>
              you read the internal comments instead of the API docs as
              the main<br>
              source of writing.<br>
              <br>
              In other words, literate files can serve as a guide to
              *developers* of<br>
              the code, not necessarily just to users. Though for
              non-API material,<br>
              it's useful for both.<br>
              <br>
              ## Editor updates<br>
              <br>
              - Emacs and Vim plugins would have to be updated to
              understand the new<br>
                extension, and actually behave properly when editing one
              of these<br>
                files. Probably we should have conditional syntax
              highlighting<br>
                depending on the block type that we're working on.<br>
              <br>
              ## Rustc<br>
              <br>
              Rustc would need to be able to interpret and understand
              literate Rust<br>
              code just as well as it can regular code, so that they can
              link to one<br>
              another without an additional step - otherwise this isn't
              useful. I<br>
              should be able to run Literate Rust just like it's any
              other Rust<br>
              code.<br>
              <br>
              ### Conversion<br>
              <br>
              There are relatively easy ways to do "literate -> code"
              conversion<br>
              without actually interfering with anything. Haskell has a
              sed<br>
              implementation [2] on their wiki. Re-implementing this in
              Rust would<br>
              not be a significant effort.<br>
              <br>
              I think a reasonable way to manage the conversion would be
              to have a<br>
              hidden step that moves the converted code to /tmp or
              something<br>
              similar, then compiles that code and removes the converted
              bit.<br>
              <br>
              There would be some additional voodoo required to make
              this behave<br>
              perfectly:<br>
              <br>
              - Pathnames should still show the original file.<br>
              - Line numbers can't be wonky.<br>
              - Linker would have to understand this, not sure how that
              would be<br>
                affected.<br>
              <br>
              The gist of this is that the conversion step should be as
              transparent<br>
              as possible - ideally, an absolute minimum of compiler
              code would need<br>
              to be modified, since we would have some way to
              transparently resolve<br>
              the literate file to its converted version.<br>
              <br>
              [2]: <<a moz-do-not-send="true"
href="http://www.haskell.org/haskellwiki/Literate_programming/Bird_conversion_via_sed"
                target="_blank">http://www.haskell.org/haskellwiki/Literate_programming/Bird_conversion_via_sed</a>><br>
              <br>
              Any feedback is appreciated.<br>
              <br>
                      Nathan<br>
              _______________________________________________<br>
              Rust-dev mailing list<br>
              <a moz-do-not-send="true"
                href="mailto:Rust-dev@mozilla.org" target="_blank">Rust-dev@mozilla.org</a><br>
              <a moz-do-not-send="true"
                href="https://mail.mozilla.org/listinfo/rust-dev"
                target="_blank">https://mail.mozilla.org/listinfo/rust-dev</a><br>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
Rust-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Rust-dev@mozilla.org">Rust-dev@mozilla.org</a>
<a class="moz-txt-link-freetext" href="https://mail.mozilla.org/listinfo/rust-dev">https://mail.mozilla.org/listinfo/rust-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>