F# Interactive with Emacs

123 views
Skip to first unread message

Ryan Stradling

unread,
Jan 11, 2015, 4:42:00 PM1/11/15
to fsharp-o...@googlegroups.com
Hi all,
It has been a while since I have spent a lot of time with Microsoft development tools including keeping up with the latest vsproject file formats.  I am a decent emacs user and was hoping to try F# out on OSX like I have with Clojure.  In doing so, I have hit a few problems.  I am using F# interactive 3.1.  The relevant parts of my emacs (version 24.2) init.el file looks like

(unless (package-installed-p 'fsharp-mode)
  (package-install 'fsharp-mode))
(require 'fsharp-mode)

I have used the fsharp project scaffold to generate my project https://github.com/fsprojects/ProjectScaffold.  

FSharp mode seems to kind of work so I think I have emacs configured correctly.  The problem is that I have added a dependency on Suave to my project and can't get fsi to recognize that this dependency exists.  My code looks like the below for Library.fs.

namespace valet

/// Documentation for my library
///
/// ## Example
///
///     let h = Library.hello 1
///     printfn "%d" h
///
module Library = 
  open Suave
  open Suave.Http.Successful
  open Suave.Web

  let hello num = 42


When doing a C-c C-f I get a 
 error FS0039: The namespace or module 'Suave' is not defined

However, when I build the project from the command line it all builds fine using.  If I do a C-c C-p to load the project I get a 

The required attribute in "Project" in Import is empty.


I was hoping that when sending my code to fsi in emacs that the references from the project file would be read and all would be good.  But maybe I am expecting something that is not possible.  I am trying to figure out why things are not working properly.  Should I be adding a #r?  I thought #r was more for fsharp scripts (fsx files).  Is the way I am trying to work with a fsproj not possible with F# interactive mode?

I appreciate any and all help.

Thanks,
Ryan

panesofglass

unread,
Jan 11, 2015, 11:24:14 PM1/11/15
to fsharp-o...@googlegroups.com
This is a glitch in XBuild or Xamarin Studio (I think the latter). VS projects generate fsproj files that toggle the path to FSharp.targets (full name escapes me). The Import statement typically does not have anything other than <Import Project="$(FSharpTargetsPath)" />. The simplest fix is to add a condition: <Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />.

Another oddity that I've often found in my fsproj files is an incorrect version number in the <MinimumVisualStudioVersion /> tag. In some cases, I see this:

  <PropertyGroup>
    <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">10</MinimumVisualStudioVersion>
  </PropertyGroup>
  <Choose>
    <When Condition="'$(VisualStudioVersion)' == '11.0'">

See the mismatch? I'm not sure why there's not another <When Condition=""> for version 10, but Xamarin Studio doesn't appear to work well with the above. Changing that to the following has often fixed the problem for me without having to add the Condition to the Import element (though I recommend you do add the Condition attribute to the Import element regardless):

  <PropertyGroup>
    <MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
  </PropertyGroup>
  <Choose>
    <When Condition="'$(VisualStudioVersion)' == '11.0'">


Robin Neatherway

unread,
Jan 12, 2015, 3:45:05 AM1/12/15
to fsharp-o...@googlegroups.com
Hi Ryan,

There are two separate issues here. One is the problem the other Ryan was talking about, indicated by the error "The required attribute in "Project" in Import is empty.". This either means there is a problem with your project file, or the parsing of it (done by the F# compiler services). Does your project build from the command line using `xbuild <file.fsproj>`? If the F# project scaffold generates projects that do not build on Mono this is a serious issue.

The second issue is to do with the way that FSI behaves. When you use C-c C-f, you are just sending the text of the file to FSI, as if you had entered it by hand. There is no extra magic sending the project references, which FSI does need to be told about, and no difference here as to whether the file is a .fs or .fsx. Visual Studio will also behave in the same way.

One solution is to add a section at the top of your file with a compiler directive:

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

so that this is ignored when compiling. I would instead usually use a separate .fsx file that used #load to include this .fs file however.

The Emacs mode does not currently have a facility to send the project references to FSI, or insert them into the current file as #r directives. It *does* know what they are however, once the project has been successfully loaded, so it would be possible to add that feature.

I hope this helps,
Robin


--
--
To post, send email to fsharp-o...@googlegroups.com
To unsubscribe, send email to
fsharp-opensou...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/fsharp-opensource
---
You received this message because you are subscribed to the Google Groups "F# Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fsharp-opensou...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages