Re: [MLton] RFC: implement "use" function to support explicit file dependency
Matthew Fluet <[email protected]> Fri, 7 Feb 2014 11:16:21 -0500
| Newsgroups | gmane.comp.lang.ml.mlton.devel |
|---|---|
| Message-ID | <CAMrhFL6zcaGC10Oj5TFhigX0hb7c4kGt8t=Tmq+UFH-1fzTJWw@mail.gmail.com> |
On Tue, Feb 4, 2014 at 8:10 PM, James Deng <[email protected]> wrote: > I thought this mechanism can be implemented similar to that of the ML Basis > system. Please point out if I am wrong. > > The mlb files are elaborated with the elaborateMLB function in the Elaborate > phase. I guess this phase is able to combine and substitute all the “use” > statements with file contents. (I assume the “use” is not a normal function, > but a compile time meta-programming.) It is true that you could implement a limited form of file inclusion, directly within an .sml file, in a manner that is somewhat similar to the implementation of the ML Basis System. But, it would need to be fairly restrictive ("use" is only applied to constant strings, "use" is only applied at the top-level of the file), and it might be more confusing to keep the name "use" for the feature. > For instance, the semantics of this simple file A.sml: > > local > use “B.sml”; > use “C.sml”; > in > (* use B and C here. *) > end > > > is equivalent to a mlb file A.mlb: > > local > B.sml > C.sml > in A.sml end > Note that one couldn't simply interpret "use" as textual inclusion, because SML does not allow signature and functor declarations within local. But, that's a rather minor point. The major issue is that "use" is not really compositional in the manner that one would like to express these sorts of dependencies. The issue is that if both "B.sml" and "C.sml" rely on "D.sml", the simplistic interpretation of "use" is that "D.sml" is included/elaborated/evaluated twice. Furthermore, because of generative types, "B.sml" and "C.sml" might end up incompatible in some manner, because they see different type declarations from their own inclusions of "D.sml". That's why the ML Basis System has a semantics where "Each MLB file is elaborated and evaluated only once, with the result being cached. Subsequent references use the cached value. Thus, any observable effects due to evaluation are not duplicated if the MLB file is referred to multiple times." In the ML Basis System, if both "B.mlb" and "C.mlb" both reference "D.mlb", then "D.mlb" is elaborated/evaluated only once, but the same environment is made available in both "B.mlb" and "C.mlb". That said, James's original point is well taken. One difficulty with SML programming is that a single SML file is not, in some sense, self-contained. It is very true that in most languages, if I see something in a file that doesn't appear to be defined in the file, then I jump to the top of the file and look at the "#include" (C/C++), "import" (Java, Haskell), "open" (OCaml), etc. to see some amount dependency information. The ML Basis System was designed to work with this limitation of SML programming, and so the "implicit dependencies" is not so much a "feature" in the sense of desirable as a "feature" in the sense of a simple characteristic of the system. On the other hand, with the ML Basis System, one could program in a style that exposes very explicit import and export dependency information. One can adopt a style whereby every .sml file is accompanied by a .mlb file that exactly explains its imports and exports. Christopher Cramer mentioned that this is a style that he has adopted: http://article.gmane.org/gmane.comp.lang.ml.mlton.user/1486. With James's example above, we might write "A.mlb" with: ---------- local local (* IMPORTS *) local B.mlb in structure B1 structure B2 end (* "import" B1 and B2 from B.mlb (which corresponds to B.sml) *) local C.mlb in structure C end (* "import" C from C.mlb (which corresponds to C.sml) *) in (* CODE *) A.sml (* may reference B1, B2, and C (but nothing else) *) end in (* EXPORTS *) structure A1 structure A2 end ---------- If one were to globally adopt this style, then it would be nice for some compiler support, in the sense that we would like to push the IMPORTS and EXPORTS into the A.sml file in some manner --- though it would necessarily be some kind of extension over Standard ML: ---------- import B.mlb (structure B1, structure B2) import C.mlb (structure C) export (structure A1, structure A2) ;; (* CODE *) ---------- Finally, I think it is a very good thing that SML (and most programming-in-the-very-large systems layered on top of SML, such as SML/NJ's Compilation Manager and MLton's ML Basis System) allow individual .sml files to define multiple module-level constructs (structures, signatures, functors). This is in contrast to a number of other languages that require a one-to-one mapping of module-level constructs to files. ------------------------------------------------------------------------------ Managing the Performance of Cloud-Based Applications Take advantage of what the Cloud has to offer - Avoid Common Pitfalls. Read the Whitepaper. http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk _______________________________________________ MLton-devel mailing list [email protected]; [email protected] https://lists.sourceforge.net/lists/listinfo/mlton-devel