Is there any way to use JavaScript attribute by default? - f#

I just want somehow to say "I want all methods in this project use [JavaScript]"
Manually annotation every method is annoying

F# 3 lets you mark a module with the ReflectedDefinition attribute (aka [JavaScript] in WebSharper) which marks all the methods underneath.
See More About F# 3.0 Language Features:
(Speaking of uncommon attributes, in F# 3.0, the
[< ReflectedDefinition >] attribute can now be placed on modules and
type definitions, as a shorthand way to apply it to each individual
member of the module/type.)

I think Phil's answer is the way to go - when you can mark an entire module or type, it does not add too much noise and it also allows you to distinguish between server-side and client-side code in WebSharper.
Just for the record, the F# compiler is open-source and so someone (who finds this issue important) could easily create branch that would add an additional command line attribute to override the setting. I think this is just a matter of adding the parameter and then setting the default value of the reflect flag in check.fs (here is the source on GitHub).
At the moment, the main F# repository does not accept contributions that add new features (see the discussion here), but it is certainly a good way to send a feature request to the F# team :-)

If you annotate all your code with the JavaScript attribute, the WebSharper compiler will try to translate everything to JavaScript. A rule of thumb in WebSharper development is to separate server-side and client-side code, so you can simply annotate the module/class containing client-side code instead of every function/member if you're targeting .NET 4.5.
namespace Website
open IntelliFactory.WebSharper
module HelloWorld =
module private Server =
[<Rpc>]
let main() = async { return "World" }
[<JavaScript>] // or [<ReflectedDefinition>]
module Client =
open IntelliFactory.WebSharper.Html
let sayHello() =
async {
let! world = Server.main()
JavaScript.Alert <| "Hello " + world
}
let btn =
Button [Text "Click Me"]
|>! OnClick (fun _ _ ->
async {
do! sayHello()
} |> Async.Start)
let main() = Div [btn]
type Control() =
inherit Web.Control()
[<JavaScript>]
override __.Body = Client.main() :> _

Related

Using log4net in F# as a singleton separate class

I've seen a few posts about implementing log4net using C# and F# - but I am wanting to implement it as a singleton in a separate class ( so I can call from anywhere )
I am loosely following this post. I just think my translation from C# to F# is a bit behind.
I set up the log4net.config and run the following code at the start of my console app
namespace MyNamespace
open System.IO
open log4net.Config
module LoggerConfigure =
let configureLogging() =
FileInfo("log4net.config")
|> XmlConfigurator.Configure
|> ignore
The following ( from the link above ) is C# and I want it to be an F# class that can be called as a singleton.
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
My primary quwation is - I'm a bit stuck converting that to an F# class. How do I do that?. Any ideas you have around the whole concept is appreciated as well.
There may be cases where a more sophisticated handling of singletons is needed, but I believe that standard global let declaration in an F# module would work well enough.
You just need to make sure that the configuration code is run before the log value is accessed, which you can do by making that call as part of the let binding that defines log:
module LoggerConfigure =
let configureLogging() =
FileInfo("log4net.config")
|> XmlConfigurator.Configure
|> ignore
log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)
let log = configureLogging()
Or if you prefer to put everything in a single expression:
module LoggerConfigure =
let log =
FileInfo("log4net.config") |> XmlConfigurator.Configure |> ignore
log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType)

How to use FileSystemWatcher in F#

I want to watch a directory for file changes (create, edit, rename, delete) and do something, such as calling a function, when a change is detected. From what I can tell, FileSystemWatcher should do this. However, there is no sample code for F# on the documentation page, and elsewhere on the web seems scarce as well.
From what I've found, the following is at least part of the answer:
let fileSystemWatcher = new FileSystemWatcher()
fileSystemWatcher.Path <- #"C:\temp" // I'm actually using a variable here
fileSystemWatcher.NotifyFilter <- NotifyFilters.LastWrite
fileSystemWatcher.EnableRaisingEvents <- true
fileSystemWatcher.IncludeSubdirectories <- true
fileSystemWatcher.Changed.Add(fun _ -> printfn "changed")
fileSystemWatcher.Created.Add(fun _ -> printfn "created")
fileSystemWatcher.Deleted.Add(fun _ -> printfn "deleted")
fileSystemWatcher.Renamed.Add(fun _ -> printfn "renamed")
That doesn't actually do anything, however. Some posts seem to have an Async loop to react to events, but if I use the code snippets from there F# tells me that Async.AwaitObservable is undefined.
I'd appreciate it if someone could provide a complete example of FileSystemWatcher's correct usage.
Works fine for me in FSI.
Drop the NotifyFilter bit - you're overwriting the default settings (which do include LastWrite anyway), and some of the events you care about are not being raised. NotifyFilter is an antiquated enum-flag-style field, so you can add a new value there like this:
watcher.NotifyFilter <- watcher.NotifyFilter ||| NotifyFilters.LastWrite
You don't need an async loop per se - in the example you linked to it just replaces the standard event handlers that you are already using. But if you want to use Async.AwaitObservable, look up FSharpx on nuget.

Unable to use protected events in F#

Let's say we have the following C# class
public class Class1
{
protected event EventHandler ProtectedEvent;
protected virtual void OverrideMe() { }
}
It seems to be impossible to use the ProtectedEvent in F#.
type HelpMe() as this =
inherit Class1()
do
printfn "%A" this.ProtectedEvent
member x.HookEvents() =
printfn "%A" x.ProtectedEvent
member private x.HookEvents2() =
printfn "%A" x.ProtectedEvent
override x.OverrideMe() =
printfn "%A" x.ProtectedEvent
In this example I have attempted to call printfn on it, as there are multiple ways to hook up events in F# and I wanted to be clear that is simply the referencing of the event at all that causes the problem.
In each of the cases above the compiler complains with the following error
A protected member is called or 'base' is being used. This is only
allowed in the direct implementation of members since they could
escape their object scope.
I understand this error, what causes it and its purpose. Usually, the work around is to wrap the call in a private member, which works fine with methods - but that does not seem to work with events. No matter what I try, it seems to be impossible to use protected events in F# unless I resort to doing something with reflection, or make some changes to the base class (which in my case is not possible).
Note that I have also tried all possible combinations of using base, this and x.
Am I doing something wrong ?
I suspect that there is something about the code that the compiler generates behind the scene when you treat the event as a first-class value that later confuses it (i.e. some hidden lambda function that makes the compiler think it cannot access the protected member). I'd say that this is a bug.
As far as I can see, you can workaround it by using add_ProtectedEvent and remove_ProtectedEvent members directly (they do not show in the auto-completion, but they are there and are accessible - they are protected, but calling them is a direct method call, which is fine):
type HelpMe() =
inherit Class1()
member x.HookEvents() =
let eh = System.EventHandler(fun _ _ -> printfn "yay")
x.add_ProtectedEvent(eh)
override x.OverrideMe() =
printfn "hello"
This compiled fine for me. It is a shame that you cannot use the protected event as a first-class value, but this at least lets you use it...

how do i create a computational expression that takes parameters?

I want to create a couple of computational expressions that would be used to access the database and return a list of items like so (I also have questions in the code comments):
let foo x y z = proc "foo" {
let! cmd = proc.CreateCommand() // can I do this?
do! In "x" DbType.Int32 // would i gain anything by replacing DbType with a union
// type since the names would match actual data types?
do! In "y" DbType.String 15;
cmd?x <- x
cmd?y <- y
use! r = cmd.ExecuteReader() // would this be bad form for creating a workflow builder?
return! r {
let item = MyItem()
do! item.a <- r.GetInt32("a")
do! item.a <- r.GetString("b")
do! item.c <- r.GetDateTime("c")
yield! item
}
}
How can I create a workflow builder such that an instance of it takes a parameter?
let proc name = ProcedureBuilder(connStr, factory) // how do I do this?
Yes, you can do this. You can use computation expression syntax after any expression with a type statically known to expose the right methods. So the following code works (but doesn't do anything particularly interesting):
let f x = async
let v = f "test" { return 1 }
Here, f has type 'a -> AsyncBuilder, so f "test" has type AsyncBuilder and can be followed with computation expression syntax. Your example of let proc name = ProcedureBuilder(connStr, factory) is perfectly fine, assuming that ProcedureBuilder is defined appropriately, though you presumably want name to appear somewhere in the constructor arguments.
The answer from Keith (kvb) is correct - you can use parameterized computation builders. The syntax of computation expressions is:
<expr> { <cexpr> }
So, the builder can be created by any expression. Usually, it is some value (e.g. async) but it can be a function call or even a constructor call. When using this, you would typically define a parameterized builder and then pass the argument to a constructor using a function (as #kvb suggests).
I actually wrote an example of this, not a long time ago, so I can share an example where - I think - this is quite useful. You can find it on F# snippets: http://fssnip.net/4z
The example creates a "special" asynchronous computation builder for ASP.NET MVC that behaves just like standard async. The only difference is that it adds Run member that uses AsyncManager (provided by ASP.NET) to execute the workflow.
Here are some relevant parts from the snippet:
/// A computation builder that is almost the same as stnadard F# 'async'.
/// The differnece is that it takes an ASP.NET MVC 'AsyncManager' as an
/// argumnet and implements 'Run' opration, so that the workflow is
/// automatically executed after it is created (using the AsyncManager)
type AsyncActionBuilder(asyncMgr:Async.AsyncManager) =
// (Omitted: Lots of boilerplate code)
/// Run the workflow automatically using ASP.NET AsyncManager
member x.Run(workflow) =
// Use 'asyncMgr' to execute the 'workflow'
The snippet wraps the construction in a base class, but you could define a function:
let asyncAction mgr = new AsyncActionBuilder(mgr)
And then use it to define asynchronous action in ASP.NET MVC:
member x.LengthAsync(url:string) = asyncAction x.AsyncManager {
let wc = new WebClient()
let! html = wc.AsyncDownloadString(url)
return html.Length }

Using F#'s built-in async support with *Async() methods

How do I use F#'s built-in support for async operations classes exposing the Event-based Asynchronous Pattern such as WebClient class?
let Download(url : Uri) =
let client = new WebClient()
let html = client.DownloadString(url)
html
When I try to change this to use "let!" in an async block (say as described in Soma's recent post)
let Download(url : Uri) =
async {
let client = new WebClient()
let! html = client.DownloadStringAsync(url)
return html }
I get an error message:
Type constraint mismatch. The type unit is not compatible with type Async<'a> The type 'unit' is not compatible with the type 'Async<'a>'
Edit: I'm really asking about the general question of using *Async() methods, WebClient is just an easy example. Microsoft says "... you should expose asynchronous features using the Event-based Asynchronous Pattern [ as opposed to BeginFoo()/EndFoo() ] whenever possible ..." so I would think there should be an easy way to consume an arbitrary *Async() method from F#.
The WebClient.DownloadStringAsync method is part of the .NET framework. It'll raise an event to signal its progress, and its return type is unit, so you don't want to use it, and there's no advantage in wrapping it in an async object.
The F# PowerPack defines an extension method, val webclient.AsyncDownloadString : uri -> Async{string}:
let Download(url : Uri) =
async {
let client = new WebClient()
client.Encoding <- Encoding.GetEncoding("utf-8")
let! html = client.AsyncDownloadString(url)
return html }
Unfortunately, the choice of name clashes with the existing webclient method, which can understandably cause confusion. However, I believe all of the F# async extensions begin with Async*.
[Edit to add in response to comments:]
Usually, .NET uses the BeginFoo / EndFoo pattern for concurrency. If the types are right, you can just use Async.BuildPrimitive beginMethod endMethod, which will return an Async wrapper for the method.
Sometimes objects don't use this pattern, like the WebClient, and you actually have to use Async.AwaitEvent to wait for an event to be fired, or write your own loop to repeatedly check to see if a bool is set. Here's a nice article on converting events to Async objects.
For what its worth, if you have F# installed, you should also have the source code which will give you an idea of how the F# team implements their async extensions. On my machine, the relevant file is located at:
C:\Program Files\FSharp-1.9.6.16\source\fsppack\FSharp.PowerPack\AsyncOperations.fs

Resources