2009/11/30 Baojian Hua <span dir="ltr"><<a href="mailto:huabj@mail.ustc.edu.cn">huabj@mail.ustc.edu.cn</a>></span><br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
We've been useing MLton for over 7 years for our research<br>
projects, and recently we're planning to read and hack some source<br>
code of MLton (and hopefully we can contribute in the<br>
future).<br></blockquote><div><br>It would be great if you could add a link to your project(s) to <a href="http://mlton.org/Users">http://mlton.org/Users</a>.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
And we start by reading sources in "lib/mlton/basic/", but<br>
the documentation is rare, so we have to send some questions here:<br>
in files "layout.sig, sml", this data structure:<br>
<br>
datatype t = T of {length: int,<br>
tree: tree}<br>
and tree =<br>
Empty<br>
| String of string<br>
| Sequence of t list<br>
| Align of {force: bool, rows: t list}<br>
| Indent of t * int<br>
<br>
Does the "force" mean we must align several line?</blockquote><div><br>Looking at layout.sig, the comments note:<br><br> (* layout the objects on separate lines*)<br> val align: t list -> t<br> (* layout the objects on separate lines, if necessary *)<br>
val mayAlign: t list -> t<br><br>where, "align" corresponds to "Align {force = true, ...}" and "mayAlign" corresponds to "Align {force = false, ...}".<br>So, "force = true" requires that each element be printed and aligned on a separate line.<br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> And in calculating<br>
the length, I'd expect to see this:<br>
<br>
case tree<br>
of Align {rows, ...} => max (rows) (* the longest one *)<br>
| _ =><br>
<br>
but the code is this:<br>
<br>
case tree<br>
of Align {rows, ...} => \Sigma (rows) (* the whole *)<br>
| _ =><br></blockquote><div><br>The "length" field is really a "size" measure. That is, it measures the total size of all the string elements in the layout (+1 for each space that will appear between Align elements). It does not measure the length of a line of the layout; note, for example, that "length" is not incremented on an Indent.<br>
<br>Looking at the "print" function (layout.sml:122) and the "Align" case (layout.sml:168), you see that the length is ignored when force == true; in that case, each layout element is printed on a separate line. When force == false, the length is used to determine if all of the layout elements can be printed on the same line.<br>
<br>One subtlety is that if one does:<br> val lay = mayAlign [align [str "A", str "B"], align [str "C", str "D"]]<br> val () = print (lay, TextIO.print)<br>then you will get the output:<br>
A B C D<br>Note that the "force = true" on the inner aligns is ignored, because the outer align put all of its inner layout elements on to one line.<br><br>Hope that helps.<br><br></div></div>