Re: Interactive SML use from Emacs, a question of approach
Christopher Cramer <[email protected]>
| Newsgroups | gmane.comp.lang.ml.mlton.user |
|---|---|
| Message-ID | <[email protected]> |
On Fri, Oct 11, 2013 at 12:45:04PM -0500, Grant Rettke wrote: > 1. Interactively send code to a REPL. Let the environment grow and > evolve. Restart the interpreter as needed. > > 2. Start a fresh REPL every time code is evaluated so that the > entirety of the system state is known and predictable. > > When I set up OCaml mode (tuareg), I did it like #2 and it worked > fine. Now I'm setting up SML mode, and I'm curious how other people do > their real development workflow in regards to REPL and development > management. MLton doesn't have an interactive REPL, so one could say #2 is the only way. But in practice most people seem to use SML/NJ or Poly/ML for development and then use MLton for the final build. MLton has very few deviations from the Definition, so you just need to make sure you don't use any SML/NJ or Poly/ML extensions. Personally, I use Vim and just use MLton to compile and nothing else. For large programs it can take a long time to compile everything, so what I do is type-check small, single files at a time (with -stop tc). There are two things that are necessary to make this work: 1. Split up the code into small (1000 lines or less ideally) files, with a simple external interface for each file, using opaque types. Otherwise the type errors will drive you crazy. 2. Create one MLB file (or more, see below) per SML source file. This encapsulates the dependencies and annotations for a given source file in one discrete place. Example MLB, which I name foo.mlb: local $(SML_LIB)/basis/basis.mlb bar.mlb baz.mlb in foo.sml end And you can then just run "mlton -stop tc foo.mlb" to test that everything is OK with foo.sml. It will take a couple seconds or less, if you kept foo.sml small. This has the bonus that you don't need to decide which order everything should go in, in one big confusing MLB. Note that even if a source file doesn't depend on anything else other than the Basis Library, you still make an MLB for it, because the semantics of referencing a source file directly are different. If a source file is referenced multiple times, it's loaded multiple times and creates distinct, incompatible signatures/structures/, whereas if an MLB file is referenced multiple times, it's only loaded once. Most of the time, with defensive use of the type system (types can be used to enforce invariants at compile-time, much like "assert" is used in certain other languages) this is actually sufficient, and I don't write tests for the code. But when I want to write tests (and I think that basically any time you have the desire to try something out in a REPL, you should probably just create some test code, so you can reuse it), I follow these steps: 1. put the test code into a functor named Test (). foo.sml: signature FOO = sig (* ... *) end structure Foo = struct (* ... *) end functor TestInternal () = struct (* ... *) end structure Foo :> FOO = Foo functor TestExternal () = struct (* ... *) end functor Test () = struct structure Z = TestInternal () structure Z = TestExternal () end 2. create an MLB, foo-all.mlb, which contains the dependencies and the source file: local $(SML_LIB)/basis/basis.mlb bar.mlb in foo.sml end 3. create an MLB, foo.mlb, which elides the test functors and can be referenced by other MLBs: local foo-all.mlb in signature FOO structure Foo end 4. create a test source program, test.sml: structure Z = Test () 5. create an MLB, foo-test.mlb, for testing: local foo-all.mlb in test.sml end Then I can make changes to the code (including the test code) in foo.sml, and test it in isolation from the rest of the code by running "mlton foo-test.mlb" and running the resulting program. So I guess you could say I'm in camp #2. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. ------------------------------------------------------------------------------ October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60134071&iu=/4140/ostg.clktrk