Search code examples
macosxamarinf#nugetsuave

F# Interactive, NuGet, and External libraries


I'm trying to run the demo code for suave (a webserver) in Xamarin Studio 5.9.8 on OS X El Capitan.

module ServerTest =
    open Suave                 // always open suave
    open Suave.Http.Successful // for OK-result
    open Suave.Web             // for config

    startWebServer defaultConfig (OK "Hello World!")

It works as expected when I actually build the code. But when I try running it interactively, with ctrl + return, I get the error The namespace or module 'Suave' is not defined. I've looked around, and it looks like it's possible to use libraries interactively with Visual Studio. Is there a way to get this to work on OS X?


Solution

  • When you build your code, the information about referenced DLLs is contained not in the code itself, but elsewhere (the project file). But when you execute the code in FSI, all FSI sees is the code. It doesn't have a project file from which to get references.

    But since FSI still needs to load referenced DLLs occasionally (otherwise, it wouldn't be very useful), it offers a way to encode them in the code. This way is described in the page you linked - specifically, the #r directive.

    Unfortunately, these directives are not supported when you build the code with the compiler. The compiler will generate an error when it sees them.

    So it would seem that you have a choice: either execute the code with FSI or build it with compiler. Can't use the same code for both.

    Fortunately, there are a couple of tricks to work around this.

    First, you could leverage a special conditional compilation variable called INTERACTIVE and put the #r directive inside an #if such that only FSI will see it, but compiler won't:

    #if INTERACTIVE
       #r "./path/to/my.dll"
    #endif
    

    Second, you could create a separate script file that will load references and then load your actual code file:

    #r "./path/to/my.dll"
    #load "./my_code.fs"
    

    And then execute this script file with FSI.

    In both these cases, the paths are relative to the script file.
    This means that the "not found" error you're getting is probably due to incorrect path to the Suave DLL. I seriously doubt that the DLL is located in the same directory with the code file. And also that it has no extension.