Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile with standalone flag gives compilation errors in client code

I'm attempting to compile Zero29 with the --standalone compiler flag. The project itself compiles fine, but I have a unit test project that exercises some code in the Zero29 project, even though it's an executable program (.exe).

Everything works fine without the --standalone compilation flag.

However, when I add the --standalone compilation flag to the Zero29 project, the Zero29 project compiles fine, but in the unit test project, the compiler complains about this Discriminated Union defined in the Zero29 project:

namespace Ploeh.ZeroToNine

open System
open Ploeh.ZeroToNine.Versioning

type Arg =
    | Assign of Version
    | AssignRank of Rank * int
    | Increment of Rank
    | ListVersions
    | ShowHelp
    | Unknown of string list

The unit test project directly references the Zero29 project:

Zero29.UnitTests --references--> Zero29 (where --standalone is added)

When I attempt to compile the entire solution, the Zero29 project compiles with the --standalone flag, but then compilation of Zero29.UnitTests fails. There are several errors, but they are all the same, so here's a single example:

error FS0039: The value or constructor 'Assign' is not defined

Which points to the third line of this code:

let ParseAssignVersionReturnsCorrectResult(version : string) =
    let actual = [| "-a"; version |] |> Args.Parse
    verify <@ [Assign(Version version)] = (actual |> Seq.toList) @>

The strange thing is that while the compiler complains about Assign in the third line of this code snippet, it doesn't complain about the use of Args.Parse, even though it's defined in the same code file as the Arg Discriminated Union.

Why does it do that, and how can I resolve this issue?

(I've attempted to distil the problem here, but the links I've provided point to the actual code files on GitHub, if more information is required.)

like image 798
Mark Seemann Avatar asked Mar 23 '14 16:03

Mark Seemann


People also ask

How do you fix a compilation error?

If the brackets don't all match up, the result is a compile time error. The fix to this compile error is to add a leading round bracket after the println to make the error go away: int x = 10; System.

Which is not a compilation error?

* Option A, placing a semicolon at the end of the first line of an IF statement is not a compilation error so it is correct.


1 Answers

Libraries compiled with the --standalone switch cannot expose any F# datatypes. This is, for one, expressly stated in Pickering (2007), p. 210. In your case, a discriminated union is one of these prohibited types. The fact that the file is an executable changes nothing here: it becomes a library the moment you attempt to use it as one.

There have been also multiple reports (for example, here and here) that even libraries compiled with --standalone behave, quoting one of these sources, “funky.” It would be safe to say that the use of this switch should perhaps be limited to stand-alone executables only (and they cannot pretend to be a library even when under unit tests).


Pickering R. (2007). Foundations of F#. Apress.

like image 102
kkm Avatar answered Oct 25 '22 18:10

kkm