[MLton] On "layout.sig, sml"

Matthew Fluet matthew.fluet at gmail.com
Tue Dec 1 13:29:30 PST 2009


2009/11/30 Baojian Hua <huabj at mail.ustc.edu.cn>

> We've been useing MLton for over 7 years for our research
> projects, and recently we're planning to read and hack some source
> code of MLton (and hopefully we can contribute in the
> future).
>

It would be great if you could add a link to your project(s) to
http://mlton.org/Users.

And we start by reading sources in "lib/mlton/basic/", but
> the documentation is rare, so we have to send some questions here:
> in files "layout.sig, sml", this data structure:
>
> datatype t = T of {length: int,
>                   tree: tree}
> and tree =
>   Empty
>  | String of string
>  | Sequence of t list
>  | Align of {force: bool, rows: t list}
>  | Indent of t * int
>
> Does the "force" mean we must align several line?


Looking at layout.sig, the comments note:

      (* layout the objects on separate lines*)
      val align: t list -> t
      (* layout the objects on separate lines, if necessary *)
      val mayAlign: t list -> t

where, "align" corresponds to "Align {force = true, ...}" and "mayAlign"
corresponds to "Align {force = false, ...}".
So, "force = true" requires that each element be printed and aligned on a
separate line.


> And in calculating
> the length, I'd expect to see this:
>
> case tree
>  of Align {rows, ...} => max (rows)  (* the longest one *)
>  | _ =>
>
> but the code is this:
>
> case tree
>  of Align {rows, ...} => \Sigma (rows)  (* the whole *)
>  | _ =>
>

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.

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.

One subtlety is that if one does:
  val lay = mayAlign [align [str "A", str "B"], align [str "C", str "D"]]
  val () = print (lay, TextIO.print)
then you will get the output:
A B C D
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.

Hope that helps.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mlton.org/pipermail/mlton/attachments/20091201/883571a5/attachment.htm


More information about the MLton mailing list