How to include Akka.net framework for F# in VSCode - f#

I am trying to use Akka.NET for F# in VSCode using this example I found on the internet.
Code
// ActorSayHello.fsx
#time "on"
// #load "Bootstrap.fsx"
open System
open Akka.Actor
open Akka.Configuration
open Akka.FSharp
open Akka.TestKit
// #Using Actor
// Actors are one of Akka's concurrent models.
// An Actor is a like a thread instance with a mailbox.
// It can be created with system.ActorOf: use receive to get a message, and <! to send a message.
// This example is an EchoServer which can receive messages then print them.
let system = ActorSystem.Create("FSharp")
type EchoServer =
inherit Actor
override x.OnReceive message =
match message with
| :? string as msg -> printfn "Hello %s" msg
| _ -> failwith "unknown message"
let echoServer = system.ActorOf(Props(typedefof<EchoServer>, Array.empty))
echoServer <! "F#!"
system.Shutdown()
But I am getting this error
ActorSayHello.fsx(6,6): error FS0039: The namespace or module 'Akka' is not defined.
I have configured ionide plugin in VScode and am able to run F# without Akka.NET. I installed Akka.NET using the following command
dotnet add package Akka.FSharp --version 1.4.10
The library got added automatically added to .fsproj file. This is the output of the command
Any help would be greatly appreciated. Thank you!

Since you are using a script file it doesn't contain any project reference.
Instead you can use nuget references directly from the script!
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
Another caveat that might occur is that F# interactive needs a --langversion:preview flag to be able to use nuget references. Setting "FSharp.fsiExtraParameters": ["--langversion:preview"] in the VSCode settings.json did the trick for me.
And the last bit that I had to change to make it compile was to replace system.Shutdown() with system.Terminate() because Shutdown method was deprecated and removed.
Here is the full listing with changes mentioned above:
// ActorSayHello.fsx
#time "on"
#r "nuget: Akka.FSharp"
#r "nuget: Akka.TestKit"
// #load "Bootstrap.fsx"
open System
open Akka.Actor
open Akka.Configuration
open Akka.FSharp
open Akka.TestKit
// #Using Actor
// Actors are one of Akka's concurrent models.
// An Actor is a like a thread instance with a mailbox.
// It can be created with system.ActorOf: use receive to get a message, and <! to send a message.
// This example is an EchoServer which can receive messages then print them.
let system = ActorSystem.Create("FSharp")
type EchoServer =
inherit Actor
override x.OnReceive message =
match message with
| :? string as msg -> printfn "Hello %s" msg
| _ -> failwith "unknown message"
let echoServer = system.ActorOf(Props(typedefof<EchoServer>, Array.empty))
echoServer <! "F#!"
system.Terminate()
And the result looks like this on my machine:
Real: 00:00:00.000, ЦП: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
namespace FSI_0012.Project
Hello F#!
Real: 00:00:00.007, ЦП: 00:00:00.000, GC gen0: 1, gen1: 0, gen2: 0
val system : ActorSystem = akka://FSharp
type EchoServer =
class
inherit Actor
override OnReceive : message:obj -> unit
end
val echoServer : IActorRef = [akka://FSharp/user/$a#989929929]
val it : Threading.Tasks.Task

Related

Using and installing MathNet Package

I have installed the MathNet.Numerics package on Visual Studio 2017 using the Package Manager Console.
I have attempted to open a Source File on and execute an algorithm relating to the MersenneTwister type within the MathNet namespace.
However, when I try to generate numbers using this algorithm in F# Interactive, I am met with the error:
File1.fs(3,6): error FS0039: The namespace or module 'MathNet' is not defined. Maybe you want one of the following:
Math
Code is as per below:
module File1
open MathNet.Numerics.Random
let mersenneTwister = new MersenneTwister(42)
let a = mersenneTwister.NextDouble()
Apologies if this is unclear, I am relatively new to F# :)
Are you per change using the interactive window or running an fsx script? Cause these don't recognize your packages.
When reproducing your problem in a F# console app I got this output: Hello 0.374540.
I installed the MathNet.Numerics.fsharp nuget package (which also uses the package you mention) and used the following code in the Program.fs:
open MathNet.Numerics.Random
let hello () =
let mersenneTwister = new MersenneTwister(42)
let a = mersenneTwister.NextDouble()
printfn "Hello %f" a
[<EntryPoint>]
let main argv =
hello ()
0 // return an integer exit code
If you do want to use the nuget package from a script you can reference it in the top of your script like so (absolute or relative)
#r #"C:\Path\bin\Debug\netcoreapp3.0\MathNet.Numerics.dll"

What is wrong with this Akka.NET code?

I spent some time searching for the Akka.NET F# API. Could not find it, even though there is good C# documentation. I found the code below, dated March 2017, which looks good, but unfortunately generates an exception when I try to run it.
Two questions:
1) What is wrong with the code below?
2) Is there online documentation for the Akka.Net F# API and if yes, where is it?
Observation: I tried several other F# Akka.NET snippets I found online and all of them generated exceptions.
The URL for the code is:
https://www.seventeencups.net/building-a-mud-with-f-sharp-and-akka-net-part-one/
And here is the code I tried to run:
open System
open Akka.Actor
open Akka.Configuration
open Akka.Remote
open Akka.FSharp
let system = System.create "system" (Configuration.defaultConfig())
type GreeterMsg =
| Hello of string
| Goodbye of string
let greeter = spawn system "greeter" <| fun mailbox ->
let rec loop() = actor {
let! msg = mailbox.Receive()
match msg with
| Hello name -> printf "Hello, %s!\n" name
| Goodbye name -> printf "Goodbye, %s!\n" name
return! loop()
}
loop()
The exception message includes the following:
System.TypeLoadException: Method 'WatchWith' in type '-ctor#270' from assembly 'Akka.FSharp, Version=1.2.3.41, Culture=neutral, PublicKeyToken=null' does not have an implementation
WatchWith method has been introduced in Akka.NET v1.3, while you're using Akka.FSharp v1.2.3. You'll need to downgrade your Akka dependency back to 1.2.3 (at this point in time Akka.FSharp is not yet available in v1.3).

Embedding F# Interactive Example Throwing Exception from FSharp.Compiler.Service

I am working through the Embedding F# Interactive example from http://fsharp.github.io/FSharp.Compiler.Service/interactive.html but am having an issue with the following line throwing an exception:
let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream)
The exception thrown is:
"An unhandled exception of type 'System.Exception' occurred in FSharp.Compiler.Service.dll
Additional information: Error creating evaluation session: StopProcessing null"
My project is being run from VS2015 Enterprise Update 1, setup as a simple F# console app, with Target F# runtime being F# 4.0 with the Target Framework as 4.6. The version of FSharp.Compiler.Service downloaded from nuget is 2.0.0.2.
The Program.Fs file code I am running is here (a direct port of the example):
open System
open System.IO
open System.Text
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Interactive.Shell
[<EntryPoint>]
let main argv =
let sbOut = new StringBuilder()
let sbErr = new StringBuilder()
let inStream = new StringReader("")
let outStream = new StringWriter(sbOut)
let errStream = new StringWriter(sbErr)
// Build command line arguments & start FSI session
let argv = [| "C:\\fsi.exe" |]
let allArgs = Array.append argv [|"--noninteractive"|]
let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
let fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream)
/// Evaluate expression & return the result
let evalExpression text =
match fsiSession.EvalExpression(text) with
| Some value -> printfn "%A" value.ReflectionValue
| None -> printfn "Got no result!"
evalExpression "42+1" // prints '43'
Console.ReadLine() |> ignore
0 // return integer
Any thoughts would be appreciated.
The key to your problem is found at Compiler Services: Notes on FSharp.Core.dll
If doing dynamic compilation and execution you may also need to
include an FSharp.Core.optdata and FSharp.Core.sigdata, see below for
guidance.
When you build the application the output directory with FSharp.Core.dll is missing two files:
FSharp.Core.optdata
FSharp.Core.sigdata
You will need to find these two files and the correct versions of the files that agree with FSharp.Core.dll and copy them to the build output directory.
How to find the files using Visual Studio
From menu View -> Solution Explorer
Expand Project
Expand References
Right click FSharp.Core and select properties.
The Full Path gives the directory that should have at least the three files.
Use a file explorer to open the directory in Full Path.
Copy the two files
FSharp.Core.optdata
FSharp.Core.sigdata
to the build directory.
How to find the build directory using Visual Studio
From menu View -> Solution Explorer
Select Project
Press F4 to open the Properties Page
The Project Folder with \bin\Debug is the default when debugging with VS.
Change location of fsi.exe
Now that you have the two needed files you will also need to change the location of fsi.exe
let argv = [| "C:\\fsi.exe" |]
because I doubt that fsi.exe is in the root of your C drive.

Using F# JsonProvider within a portable class library fails

I'm trying to use the JsonProvider and I'm getting the following error when I call a function on it:
System.TypeInitializationException was unhandled
Message: An unhandled exception of type 'System.TypeInitializationException' occurred in PortableLibrary1.dll
Additional information: The type initializer for '<StartupCode$PortableLibrary1>.$PortableLibrary1' threw an exception.
I have a basic console application as follows:
module Pinit =
open FSharp.Data
type JsonT = JsonProvider<"""..\myFile.json""">
let doc = JsonT.Load("""..\nyFile.json""")
let result = doc.GeneratedAt
[<EntryPoint>]
let main argv =
printfn "%A" Pinit.doc.GeneratedAt
0
When run within the ConsoleApplication it all works as expected.
If I create an F# Portable Class library as follows:
module Pinit =
open FSharp.Data
type JsonT = JsonProvider<"""..\myFile.json""">
let doc = JsonT.Load("""..\nyFile.json""")
let result = doc.GeneratedAt
Create another Console Application and reference that Portable Class Library and call the code as follows:
open PortableLibrary1
[<EntryPoint>]
let main argv =
printfn "%A" Pinit.result
0
When I run the program then it generates the exception defined above:
I'm suspecting it's because of the versions of FSharp.Core but was wondering whether I was doing something wrong or whether there was a way to get this to work?
Versions:
-- ConsoleApplication --
FSharp.Core = 4.3.1.0
-- PortableClassLibrary --
FSharp.Core = 3.3.1.0
FSharp.Data = NuGet Version: 2.0.0
let bindings are compiled into static members, and in .NET when you have an exception in a static initializer the real exception is masqueraded.
If you turn that into a function call by changing to let result() = doc.GeneratedAt and printfn "%A" (Pinit.result()) you'll get the real exception:
Only web locations are supported
Portable profiles don't support accessing the file system. So inside the PCL you can either have web urls or load manually from an embedded resource. See here for an example: https://github.com/ovatsus/Apps/blob/master/Trains/Stations.fs#L65. Or you can load the file with File.ReadAllText in the console project and pass it to the PCL.
This was with a Portable Profile (Legacy) project, which is Profile 47 (and FSharp.Core 2.3.6.0). I then also tested with a Portable Profile project, which is Profile 7 (and FSharp.Core 3.3), and noticed it's not working correctly, it's giving this exception instead
Method not found: 'FSharp.Data.Runtime.JsonValueOptionAndPath FSharp.Data.Runtime.JsonRuntime.TryGetPropertyUnpackedWithPath(FSharp.Data.Runtime.IJsonDocument, System.String)'.
I created a github issue to track that: https://github.com/fsharp/FSharp.Data/issues/521

F# Async problem

I've written a dummy http server as an exercise in F#.
I'm using Mono 2.4.4 on Ubuntu 10.04 x86_64, with MonoDevelop.
The following code fails to compile with the error:
Error FS0039: The field, constructor or member 'Spawn' is not defined (FS0039)
Could someone try this in VisualStudio please, I don't know whether this is a Mono problem, or my problem.
I have tried several Async examples from the F# book, and they also all produce similar messages about Async.* methods.
Thanks,
Chris.
#light
open System
open System.IO
open System.Threading
open System.Net
open System.Net.Sockets
open Microsoft.FSharp.Control.CommonExtensions
printfn "%s" "Hello World!"
let headers = System.Text.Encoding.ASCII.GetBytes("HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 37\r\nDate: Sun, 13 Jun 2010 05:30:00 GMT\r\nServer: FSC/0.0.1\r\n\r\n")
let content = System.Text.Encoding.ASCII.GetBytes("<html><body>Hello World</body></html>")
let serveAsync (client : TcpClient) =
async { let out = client.GetStream()
do! out.AsyncWrite(headers)
do! Async.Sleep 3000
do! out.AsyncWrite(content)
do out.Close()
}
let http_server (ip, port) =
let server = new TcpListener(IPAddress.Parse(ip),port)
server.Start()
while true do
let client = server.AcceptTcpClient()
printfn "new client"
Async.Spawn (serveAsync client)
http_server ("0.0.0.0", 1234)
Spawn is now called Start (the library APIs have changed a bit since a couple of the books were published a few years ago).
Check the docs at
http://msdn.microsoft.com/en-us/library/ee370232.aspx

Resources