Search code examples
smlpolyml

How to access a library in Poly/ML on Windows?


I have installed Poly/ML from the "PolyML5.6-64bit.msi" installer; I can start the REPL by clicking it in the Start menu; but I don't know how to access any libraries from it? I tried doing use "something", but it results in an error like below:

> use "Math";
Exception-
   Io
     {cause = SysErr ("No such file or directory", SOME ENOENT), function =
      "TextIO.openIn", name = "Math"} raised

Similar for use "Basis" or use "Windows".

Please note that I'm a total newbie to SML; I seem to have found the use command in some generic SML tutorial, don't know if I'm using it correctly at all :/

edit: Also, the target installation directory seems to contain only the following three binary files, not sure if there should be some sources there, or not:

C:\Program Files\Poly ML>dir
 Volume in drive C is Windows
 Volume Serial Number is CENS-ORED

 Directory of C:\Program Files\Poly ML

26.02.2016  00:03    <DIR>          .
26.02.2016  00:03    <DIR>          ..
25.01.2016  14:22           681 472 PolyLib.dll
25.01.2016  14:23         8 182 784 PolyML.exe
25.01.2016  14:22            20 480 PolyPerf.dll
               3 File(s)      8 884 736 bytes

edit2: Hmmm... from some further browsing, I'm starting to think that apparently Poly/ML seems to be used by most people purely from within the "Isabelle IDE"? so maybe if I install this one, all will work out of the box? I'll try, but still the original question remains open for now.

edit3: Uhhh, the Isabelle IDE is weird, specifically no idea how to "Run" an SML file opened in it anyways :/ probably going to uninstall (i.e. delete?) it in this situation, also given the fact that I got the answer to the original question already now.


Solution

  • I use Poly/ML on Linux, not Windows. But I'm almost certain that what follows is also true on Windows.

    You don't need to use the use function to load the Basis Library's modules, which are already in the top-level environment when you start the Poly/ML REPL. For example:

    lolcathost% poly
    Poly/ML 5.6 Release
    > structure M = Math;
    structure M: MATH
    > M.pi;
    val it = 3.141592654: real
    > 
    

    You use the use function to load your own code. The argument must be either an absolute path, or a path relative to the current working directory. I have no idea if it's possible to change the current working directory in the REPL. Check here to see how to change the current working directory, if you need it.

    Also, for larger projects, you might want to use Poly/ML's make system rather than use.


    In response to your comment:

    The module PolyML.Compiler provides functions to retrieve the names of the existing values, types, signatures, structures and functors in the top-level environment.

    However, the names alone aren't terribly useful. Here are some tricks to get the REPL to tell you more.

    Types: Say you want to know what the constructors of list are.

    > datatype foo = datatype list;
    datatype 'a foo = :: of 'a * 'a foo | nil
    > 
    

    Or how the type synonym StringCvt.reader is defined.

    > datatype foo = datatype StringCvt.reader;
    type ('a, 'b) foo = 'b -> ('a * 'b) option
    > 
    

    Of course, if you use this trick on an abstract data type, you won't get much information:

    > datatype foo = datatype string;
    eqtype foo
    > 
    

    Structures: Say you want to know what the value and type components of the structure Byte are.

    > structure Foo = struct open Byte end;
    structure Foo:
      sig
        val byteToChar: Word8.word -> char
        val bytesToString: Word8Vector.vector -> string
        val charToByte: char -> Word8.word
        val packString: Word8Array.array * int * substring -> unit
        val stringToBytes: string -> Word8Vector.vector
        val unpackString: Word8ArraySlice.slice -> string
        val unpackStringVec: Word8VectorSlice.slice -> string
      end
    > 
    

    Signatures: Say you want to know what the value and type components of the signature BYTE are.

    > functor Foo (X : BYTE) = struct open X end;
    functor Foo (X: BYTE): 
      sig
        val byteToChar: Word8.word -> char
        val bytesToString: Word8Vector.vector -> string
        val charToByte: char -> Word8.word
        val packString: Word8Array.array * int * substring -> unit
        val stringToBytes: string -> Word8Vector.vector
        val unpackString: Word8ArraySlice.slice -> string
        val unpackStringVec: Word8VectorSlice.slice -> string
      end
    >