I'm using the F# CompilerServices to host a .NET scripting environment in my app, similar to the example here:
https://github.com/fsharp/FSharp.Compiler.Service/blob/master/samples/InteractiveService/Program.fs
If I evaluate an expression (EvalExpression) the data is marshalled back into the host app, but there is no obvious way to pass data in the opposite direction.
How can I pass .NET objects from the host app into the script environment?
This would be a great addition to the API exposed by the F# Interactive services!
I guess the easiest workaround would be to define some collection for storing the parameters you want to pass in inside the F# interactive session:
let parameters = new System.Collections.Generic.Dictionary<string, obj>()
Then you can use EvalExpression to get a function that stores a value in the dictionary:
(fun k v -> parameters.Add(k, v))
The host can then cast the returned object to string -> obj -> unit and use it to set parameters that will be accessible in the code running inside the service..
EDIT: For some reason, unknown to me, the above does not quite work. However, you can wrap the F# function in a .NET delegate and then it works OK. Alternatively, you can just evaluate the expression parameters and get back the whole dictionary (and then you can store the values there directly).
This did the trick for me:
fsiSession.EvalInteraction
("let env = new System.Collections.Generic.Dictionary<string, obj>()")
fsiSession.EvalExpression
("System.Action<string, obj>(fun k v -> env.Add(k, v))")
Related
I've read about Reader Monad from this article by Jorge Castillo himself and I've also got this article by Paco. It seems that both tackles the idea of Dependency Injection just in a different way. (Or am I wrong?)
I'm really confused whether I understand the whole Reader Monad and how it relates to the Simple Depenency Injection that Paco is talking about.
Can anyone help me understand these two things? Would I ever need both of them in one project depending on situations?
Your doubt is understandable, since yes both approaches share the same outcome: Passing dependencies implicitly for you all the way across your call stack, so you don't need to pass them explicitly at every level. With both approaches you will pass your dependencies once from the outer edge, and that's it.
Let's say you have the functions a(), b(), c() and d(), and let's say each one calls the next one: a() -> b() -> c() -> d(). That is our program.
If you didn't use any of the mentioned mechanisms, and you needed some dependencies in d(), you would end up forwarding your dependencies (let's call them ctx) all the way down on every single level:
a(ctx) -> b(ctx) -> c(ctx) -> d(ctx)
While after using any of the mentioned two approaches, it'd be like:
a(ctx) -> b() -> c() -> d()
But still, and this is the important thing to remember, you'd have your dependencies accessible in the scope of each one of those functions. This is possible because with the described approaches you enable an enclosing context that automatically forwards them on every level, and that each one of the functions runs within. So, being into that context, the function gets visibility of those dependencies.
Reader: It's a data type. I encourage you to read and try to understand this glossary where data types are explained, since the difference between both approaches requires understanding what type classes and data types are, and how they play together:
https://arrow-kt.io/docs/patterns/glossary/
As a summary, data types represent a context for the program's data. In this case, Reader stands for a computation that requires some dependencies to run. I.e. a computation like (D) -> A. Thanks to it's flatMap / map / and other of its functions and how they are encoded, D will be passed implicitly on every level, and since you will define every one of your program functions as a Reader, you will always be operating within the Reader context hence get access to the required dependencies (ctx). I.e:
a(): Reader<D, A>
b(): Reader<D, A>
c(): Reader<D, A>
d(): Reader<D, A>
So chaining them with the Reader available combinators like flatMap or map you'll get D being implicitly passed all the way down and enabled (accessible) for each of those levels.
In the other hand, the approach described by Paco's post looks different, but ends up achieving the same. This approach is about leveraging Kotlin extension functions, since by defining a program to work over a receiver type (let's call it Context) at all levels will mean every level will have access to the mentioned context and its properties. I.e:
Context.a()
Context.b()
Context.c()
Context.d()
Note that an extension function receiver is a parameter that without extension function support you'd need to manually pass as an additional function argument on every call, so in that way is a dependency, or a "context" that the function requires to run. Understanding those this way and understanding how Kotlin interprets extension functions, the receiver will not need to be forwarded manually on every level but just passed to the entry edge:
ctx.a() -> b() -> c() -> d()
B, c, and d would be called implicitly without the need for you to explicitly call each level function over the receiver since each function is already running inside that context, hence it has access to its properties (dependencies) enabled automatically.
So once we understand both we'd need to pick one, or any other DI approach. That's quite subjective, since in the functional world there are also other alternatives for injecting dependencies like the tagless final approach which relies on type classes and their compile time resolution, or the EnvIO which is still not available in Arrow but will be soon (or an equivalent alternative). But I don't want to get you more confused here. In my opinion the Reader is a bit "noisy" in combination with other common data types like IO, and I usually aim for tagless final approaches, since those allow to keep program constraints determined by injected type classes and rely on IO runtime for the complete your program.
Hopefully this helped a bit, otherwise feel free to ask again and we'll be back to answer 👍
I'm working on a demo where I can show how easy it is to use the SqlClient type provider in a F# library and then consume it from C#, I think this might be one way to get things into projects. Since many people using C# want to use interfaces etc. I thought I show them that it is possible to combine everything, but I don't get the expected result. I have the following F# code which works as expected in F#:
module Orders =
[<Literal>]
let connStr = """XXXXXXXXXXXX"""
type OrdersPerEmployee = SqlCommandProvider<"OrdersPerEmployee.sql", connStr>
open Orders
type IOrdersRepo =
abstract member getOrdersPerEmployee : int -> OrdersPerEmployee.Record seq
type OrdersRepo() =
interface IOrdersRepo with
member this.getOrdersPerEmployee(employeeId) =
let query = new OrdersPerEmployee()
query.Execute(employeeId)
But when I try to use it from my C# app I don't get that the getOrdersPerEmployee returns an enumerable of records, instead it returns an enumerable of objects:
IOrdersRepo repo = new OrdersRepo();
var data = repo.getOrdersPerEmployee(4).ToList();
data.ForEach(y => Console.WriteLine(y));
Console.ReadLine();
In the code above I expceted to get intellisense on y in the lambda, but nothing. Any ideas?
Because SqlCommandProvider is erasing types kind. It means types it generates can be consumed only from F#. Contrary, SqlEnumProvider from the same FSharp.Data.SqlClient library is generated types kind and can be consumed by C# (via proxy project). It works especially nice when CLIEnum=true.
For a deeper discussion on erased vs generated types see
How do I create an F# Type Provider that can be used from C#?
How do I use types declared in my host project and served over Ajax in the generated FunScript code?
For example I lets say I declare a type T and then create a REST endpoint serving data in that format. Now if I want to load the data and use it from FunScript its no longer type T.
Edited with solution based on Alfanso's answer:
Assuming type "MyType" is defined in the base F# project and data matching this type served on localhost:6543/myData
let start () =
async{
let url = "http://localhost:6543/myData"
let req = System.Net.WebRequest.Create(url)
let! data = req.AsyncGetJSON<MyType list>()
Globals.window.alert( (sprintf "%A" data) )
}
|> Async.StartImmediate
What I was missing was
req.AsyncGetJSON
Use Async.StartImmediate
Could you please post some code to see better what you're exactly trying to do? For reference, you can see an example of how to exchange type-safe JSON values using FunScript.HTML extensions in this little project. In this case:
Types are shared between server, client and database using F# records with CLIMutable and System.Data.Linq.Mapping.Table attributes: Source
For the server, I'm using ASP.NET Web API which send types as JSON transparently: Source
In the client, I'm using the WebRequest.AsyncGetJSON<'T> extension from FunScript.HTML, which in the background just issue a XMLHttpRequest, parses the result with the browser JSON.parse method and uses unbox<'T> to "cast" the object to the desired type: here, here and here.
unbox<'T> is the little trick you'll often have to use if you want to use dynamic types in a statically-typed manner in F#.
I hope this helps!
I've not been able to find a robust, general op_Dynamic implementation: can anyone point me to one? So far searches have only turned up toys or specific purpose implementations, but I'd like to have one on hand which, say, compares in robustness to C#'s default static dynamic implementation (i.e. handle lots / all cases, cache reflection calls) (it's been a while since I've looked at C#'s static dynamic, so forgive me if my assertions about it's abilities are false).
Thanks!
There is a module FSharp.Interop.Dynamic, on nuget that should robustly handle the dynamic operator using the dlr.
It has several advantages over a lot of the snippets out there.
Performance it uses Dynamitey for the dlr call which implements caching and is a .NET Standard Library
Handles methods that return void, you'll get a binding exception if you don't discard results of those.
The dlr handles the case of calling a delegate return by a function automatically, this will also allow you to do the same with an FSharpFunc
Adds an !? prefix operator to handle invoking directly dynamic objects and functions you don't have the type at runtime.
It's open source, Apache license, you can look at the implementation and it includes unit test example cases.
You can never get fully general implementation of the ? operator. The operator can be implemented differently for various types where it may need to do something special depending on the type:
For Dictionary<T, R>, you'd want it to use the lookup function of the dictionary
For the SQL objects in my article you referenced, you want it to use specific SQL API
For unknown .NET objects, you want it to use .NET Reflection
If you're looking for an implementation that uses Reflection, then you can use one I implemented in F# binding for MonoDevelop (available on GitHub). It is reasonably complete and handles property access, method calls as well as static members. (The rest of the linked file uses it heavily to call internal members of F# compiler). It uses Reflection directly, so it is quite slow, but it is quite feature-complete.
Another alternative would be to implement the operator on top of .NET 4.0 Dynamic Language Runtime (so that it would use the same underlying API as dynamic in C# 4). I don't think there is an implementation of this somewhere out there, but here is a simple example how you can get it:
#r "Microsoft.CSharp.dll"
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder
let (?) (inst:obj) name (arg:'T) : 'R =
// Create site (representing dynamic operation for converting result to 'R
let convertSite =
CallSite<Func<CallSite, Object, 'R>>.Create //'
(Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null)) //'
// Create site for the method call with single argument of type 'T
let callSite =
CallSite<Func<CallSite, Object, 'T, Object>>.Create //'
(Binder.InvokeMember
( CSharpBinderFlags.None, name, null, null,
[| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
// Run the method and perform conversion
convertSite.Target.Invoke
(convertSite, callSite.Target.Invoke(callSite, inst, arg))
let o = box (new Random())
let a : int = o?Next(10)
This works only for instance method calls with single argument (You can find out how to do this by looking at code generated by C# compiler for dynamic invocations). I guess if you mixed the completeness (from the first one) with the approach to use DLR (in the second one), you'd get the most robust implementation you can get.
EDIT: I also posted the code to F# Snippets. Here is the version using DLR: http://fssnip.net/2U and here is the version from F# plugin (using .NET Reflection): http://fssnip.net/2V
When interacting with F# libraries from IronPython it seems that Python function object are not automatically converted to the standard F# FastFunc function object when passed to a F# interface accepting a function as one of the parameters.
On the other hand, the Python function objects are nicely converted to System.Func<> if the interface is one of these.
That is, this is not easily callable from python:
let myFunc (f: float->float) =
f(3.5)
while the following works perfectly:
let myFunc2 (f: System.Func<float, float>) =
f.Invoke(3.5)
So my question is, if I want to be able to easily feed my F#-functions Python function objects, is there some way that I can convert a System.Func<> object to a FastFunc object (to be able to have a thin interface to IronPython/C# etc but be able to use the supplied function as a regular F# function deeper in the lib)?
Thanks,
Rickard
ps
I haven't enough rep to create a new tag, maybe someone could create a FastFunc tag and tag this question with it if you find it appropriate
Here:
In order to convert from the Func delegate to the FastFunc, we use the
FuncConvertExtensions class in the FSharp.PowerPack.Linq.dll assembly.
From this site: http://codebetter.com/blogs/matthew.podwysocki/archive/2008/10/15/functional-c-implementing-async-computations-in-c.aspx