I've managed to compile NaturalSpec on mono and am trying an F# library project in MonoDevelop using it. The README test fails:
module ListSpec
open NaturalSpec
[<Scenario>]
let When_removing_an_3_from_a_small_list_it_should_not_contain_3() =
Given [1;2;3;4;5]
|> When removing 3
|> It shouldn't contain 3
|> Verify
-- with the error that NaturalSpec.Syntax.shouldn't method is not found. Replacing that by a should test rectifies that. Is there a problem for mono to use a method with an apostrophe in it? Compilation works fine, so that method is seen, but cannot be found at runtime?
I ended up recompiling NaturalSpec with F# 3.0 and .NET framework 4.5 from Mono 3.0.0, and then doing exactly the same with my own project. Apparently, when you open NaturalSpec.fsproj, you get .NET 3.5 as a default. Also, even with Mono 3.0.0, the default F# was 2.0. I've installed F# from open source code drop separately and specified fsc and fsi from it as in F# preferences in MonoDevelop. Now I made that NaturalSpec a reference, and unit tests are showing up properly in MonoDevelop -- a great way to do TDD in Mono.
Related
I noticed that adding packages sometimes breaks my code. Functions like Seq.replicate and List.take that were working get red squiggly lines and the program no longer runs. Here is a detailed procedure that should replicate the problem (I am using VS Community Edition 2017):
1) Create a project.
2) Program.fs contains the code:
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
3) Add two lines of code as follows:
[<EntryPoint>]
let main argv =
let repla = Seq.replicate 10 "A"
printfn "%A" (repla |> List.ofSeq |> List.take 5)
printfn "%A" argv
0 // return an integer exit code
3) Hit Ctrl+F5, the program runs without any problems.
4) Right-click on References on the Solution Explorer. Click on Manage Nuget Packages....
5) Click on Browse.
6) Search for Newtonsoft.Json and install it.
7) Hit Ctrl+F5, the program runs without any problems. The console prints
["A"; "A"; "A"; "A"; "A"]
[||]
8) Proceed as in steps 4 to 6 and install package MathNet.Numerics using Nuget.
9) Hit Ctrl+F5, the program runs without any problems. The console prints
["A"; "A"; "A"; "A"; "A"]
[||]
10) Proceed as in steps 4 to 6 and install package MathNet.Numerics.FSharp using Nuget.
11) Click on the Program.fs tab. The dreaded red squiggly lines appeared under Seq.replicateandList.take`.
12) Hit Ctrl+F5. A dialog box pops up with the following message:
There were build errors. Would you like to continue and run the last successful build?
Questions:
a) What exactly is happening?
b) Is this an isolated case related to a problem in MathNet.Numerics.FSharp or the specific combination of packages installed, or the order in which they were installed? Or is this a common problem?
c) Is it possible to avoid this problem while using Nuget?
d) If not, is it possible to avoid this problem by installing by some other means (not Nuget)?
MathNet.Numerics.FSharp has a dependency to FSharp.Core.3.1.2.5 which replaces the current version of FSharp.Core you are using. Being quite old 3.1.2.5 lacks many functions.
This happens with other popular F# libraries such as FsCheck as well. I usually change the reference to the newest version of FSharp.Coreas that should be backward compatible.
To do so I unload the F# project and update the FSharp.Core reference in the project file to:
<Reference Include="FSharp.Core">
<Name>FSharp.Core</Name>
<AssemblyName>FSharp.Core.dll</AssemblyName>
<HintPath>$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>
Then I reload the project.
As this is a rather clunky procedure hopefully more insightful users will post a better solution.
Well, I think the OP's concerns are somewhat valid. I would discourage hand-editing the fsproj file. And also the comments are very valid too, Paket is a great tool that can simplify dependency management both in VS and Code. So here's a very simple, two part answer, where a) you can actually get your solution working using nugget and without hand-editing the project file, and b) get a quick intro to how using paket on VS.
This issue where some package downloads and old dependency that messes up other code occurs now and then and is probably due to a strategy of relying on the minimum viable version. Your issue is somewhat similar to this Q: Why can't I get suave to work.
Here's the simplest solution using just nugget:
Open a new solution with an fsharp console project
At this point your Fsharp.Core in VS2017 will be 4.1:
Now add Mathnet.Numerics.Fsharp via nugget:
Now, very unfortunately you got downgraded to F# 3.1
This is no good, so just get Fsharp.Core via nugget as well!
And voila, you're back to a working solution without needing to edit fsproj. Basically all you had to do is add the Fsharp.Core package. You could have also changed the .NET Framework option in properties and move it to .NET 4.7 with Fsharp 4.1:
Now for Part 2 of the answer with Paket (btw, the Paket plugin just got updated and I tested and it works fine). You can essentially use it as a replacement for nugget or directly edit the files. You actually need to work with two files, paket.dependencies in the solution root and paket.references in the project root. Paket.lock will be generated. Here's a two-step process to get started. Take the project you just made above and from the Tools menu in VS select Paket Dependencies Manager, do Initialize Paket, then do Convert From Nuget:
With this you can keep managing your dependencies with nuget or use paket if you like. Next I will add Newtonsoft.JSON to the references. Double-click on the paket.dependencies file and add the following line: nuget Newtonsoft.Json 10.0.3 restriction: >= net452 , you only actually need Newtonsoft.Json in there but we don't want to download the whole interweb called .NetCore. Also add this line to paket.references (you can just click on it in the project explorer): Newtonsoft.Json. And the run Tools | Paket | Install:
Paket.dependencies:
Paket.references:
And Run Paket Install:
And you will have Newtonsoft.JSON installed. Usually you don't need to specify a version of framework restriction, however it has some pre-release package that you might not want, and also I assume you don't need the .netcore dependencies.
You can actually right click and try install this package from the references Add Package menu, but you will bump into dependency errors.
The following F# fragment seems to be valid only if compiled in ML compatibility mode (run it here):
let i = (1 lxor 5)
However I can't compile it in a trivial project in Visual Studio 2012 or using fsc.exe from the command line. I get the error:
error FS0039: The value or constructor 'lxor' is not defined
Reading the F# spec it says
Although F# reserves several OCaml keywords for future use, the /mlcompatibility option enables the use of these keywords as identifiers.
It then lists lxor as one such operator. So I tried the command line fsc.exe Program.fs --mlcompatibility (version 11.0.60610.1), but it stil get the same error.
The documentation for fsc.exe seems to indicate that the mlcompatbility option only ignores warnings. I didn't see any other relevant options in fsc's documentation or project options in VS to enable compatibility.
All of the other SO questions about F#/ML compatibility seem to be related to which language constructs can be used, but all I'm looking for is how to actually compile in compatibility mode. Do I have to open a specific namespace, reference another assembly, or do something else?
Update
I have also tried using the open source compiler fsharpc (F# 3.0) on Mono on Ubuntu 13.04. The result is the same as fsc.
The --mlcompatibility option only turns off warnings, so this looks like a regression. YOu can verify this by searching the source for all references to mlcompatibility here https://github.com/fsharp/fsharp/search?q=mlCompatibility&type=Code.
When calling fsc (fsharpc on non-Windows systems), the compiler options go before the source filenames. So the correct way to call it would be something like:
fsc -o:MyProgram.exe --mlcompatibility Program.fs
When compiling with Visual Studio, you can go into the project's properties and add --mlcompatibility to the Other flags box:
Hello I downloaded Z3 from http://z3.codeplex.com/ and then opened the Z3 solution in Visual Studio 2012. (While I'm not totally new to VS I haven't used it in over 10 years). There are 9 projects in this solution but I am having a hard time telling which I ought to be using. I can guess at some of them, but others aren't very clear. Eg. what is the difference between Microsoft.Z3 and Microsoft.Z3V3 ? Can anyone briefly explain what the different projects are and which ones to build?
Anyway just for kicks I tried building the top level solution but got the following errors
Error 1 error RC1015: cannot open include file 'afxres.h'. C:\Projects\z3-src-4.1.2\z3\dll\dll.rc 10 1 dll
Error 2 (same as Error 1 except in shell.rc)
Error 3 error LNK1104: cannot open file 'C:\Projects\z3-src-4.1.2\z3\Debug\z3_dbg.lib' C:\Projects\z3-src-4.1.2\z3\test_capi\LINK test_capi
Trying to build just the MS.Z3 project still gives me Error 1.
My eventual goal is to invoke Z3 from say an F# program. Can someone provide some guidance for how to do this?
Any help would be appreciated.
EDIT
This answer reflects the directory structure used in Z3 version <= 4.1.1. In version 4.3, the code base has been reorganized/simplified.
END EDIT
Which version of Visual Studio are you using? I'm asking because I want to reproduce the behavior you described.
The easiest way to build Z3 is described here.
You should use the Visual Studio Command Prompt, and execute msbuild. It seems you tried that, and got errors. Here is a short description of each project folder:
lib: the Z3 source code is here. This is the important folder. For visual studio users, it generated a static library.
dll: project for wrapping the static library as a Windows DLL. This is irrelevant for users in other platforms.
shell: uses the static library from lib to build z3.exe.
test: a bunch of unit tests. It produces test.exe.
Microsoft.Z3: .Net API. It is the official .Net API (C#, Visual Basic, F#, etc) for Z3. This is the API you should use with F#.
Microsoft.Z3V3: It is the old .NET API. It was the API available in Z3 3.x. We maintain it because some users still use it.
test_capi: Application that tests the Z3 C API.
maxsat: Small application that implements two maxsat algorithms on top of the Z3 API.
So I'm just getting started with F#, and I'm encountering a very weird issue where I get a System.MissingMethodException thrown when using certain methods from the FSharp PowerPack.
This does not happen for all methods in the same module. It also does not happen if I compile my assembly as an Application instead of a class library.
Reproduction steps:
Create 2 assemblies, one Class Library and one Application.
Add nunit.framework and the FSharp.PowerPack DLLs as references to both assemblies.
Create the following test fixture in each assembly.
open NUnit.Framework
[<TestFixture>]
type Tests() = class
[<Test>]
member self.OfSeq() =
// Will always succeed
Matrix.Generic.ofSeq [[1]] |> ignore
[<Test>]
member self.OfList() =
// Will fail under certain conditions with a System.MissingMethodException
Matrix.Generic.ofList [[1]] |> ignore
end
Compile both assemblies.
Open each assembly in NUnit and run all the tests.
When I do this the Application runs just fine (all tests pass), but the Class Library fails with the following exception:
System.MissingMethodException : Method not found: 'Microsoft.FSharp.Math.Matrix`1<!!0> Generic.ofList(Microsoft.FSharp.Collections.FSharpList`1<Microsoft.FSharp.Collections.FSharpList`1<!!0>>)'.
at Temp2.Tests.OfList()
What is going on here?
Another method that produces the issue is matrix.PermuteColumns.
Additional Info:
I'm compiling both assemblies for .NET 4.5
I'm compiling using Visual Studio 2012 RC
I'm using NUnit version 2.5.10.11092
I'm using FSharp PowerPack version 2.1.3.1 (though the DLL properties state that it's 2.0.0)
Let me know if there's additional information that would be of use.
(Answer for future reference since this Q was the first hit on searching.)
With Visual Studio 2013, with the "F# MSTest" online project template referenced by Brian, neither of Brian's suggestions helped (for a start the target of the testing is a library project without App.Config).
However I eventually found that the test project was set to use F#3 runtime (with FSharp.Core V4.3.0.0). Changing this to F# v3.1 (FSharp.Core V4.3.1.0) fixed the issue.
I wonder if this is related to binding redirects. You may need to copy the app.config in the application project to the library project.
This sounds similar to a known issue that I'm currently writing a blog post about for the F# team blog (probably to appear in the next few weeks) regarding MSTest rather than NUnit. I would try copying the app.config into the library project, and if that doesn't work, then use the online template for unit testing here:
http://visualstudiogallery.msdn.microsoft.com/51ebe64a-899b-4959-8c24-b0148ed6b264
and additionally select 'TEST\Test Settings\Select Test Settings File' from the menu in VS, and point it at the 'MSTest.runsettings' file included in the unit test project template. I expect that one of those two tweaks will fix it in the MSTest case.
This is doubtless something obvious, but downloading the F# PowerPack from codeplex and running fshtmldoc produces this error:
clements$ mono ./fshtmldoc.exe FSharp.PowerPack.dll
Processing 'FSharp.PowerPack.dll'...
Unexpected failure while writing HTML docs: An exception was thrown by the type initializer for Microsoft.FSharp.Metadata.AssemblyLoader
This is using mono 2.6.3, F# 2.0 1.9.9.9, & OS X 10.6.3 on a 32-bit intel processor.
Any help would be appreciated.
Many thanks,
John Clements
(repost from powerpack online discussion group--no response there)
At IntelliFactory we are so fed up with fshtmldoc.exe that we started an alternative project:
https://bitbucket.org/IntelliFactory/if-doc
It is still in beta but it quickly approaching being useful. I have not tried it on Mono yet but am interested in supporting it on Mono.
The key difference between our tool and fshtmldoc is that our tool uses Mono.Cecil instead of linking to the assemblies being documented. This means that it does not fail when those assemblies are in a different folder or their references are missing.