Style guidelines for global variables in F# - f#

For a project I am working on I need a global variable(technically I don't, I could build it and then pass it to every single function call, and let every single function call know about it, but that seems just as hacky, less readable and more work.)
The global variables are look up tables(endgame, opening book and transpositions/cache) for a game.
The fact that some of the code may lose some of it's indempotent behavior is actually the point(speedups) in short, yes I know global mutable state is bad, it's really worth it in this case(10x+ performance improvement)
So here's the question, "build a singleton or use a static value in a static class with combinators"
They are effectively identical but I am curious what people have done before on this sort of problem
Or alternatively, should I be passing the thing around to everyone(or at least a reference to it anyways),is that really the best answer?

Here is a solution similar to the one posted by #Yin Zhu's, but using abstract types to specify a usage interface for the mutable value, a local definition to encapsulate it and object literals to provide an implementation (this is taken from Expert F#--which is co-authored by Don Syme):
type IPeekPoke =
abstract member Peek: unit -> int
abstract member Poke: int -> unit
let makeCounter initialState =
let state = ref initialState
{ new IPeekPoke with
member x.Poke(n) = state := !state + n
member x.Peek() = !state }

You can also do it with static fields, like this:
type Common() =
static let mutable queue : CloudQueue = null
static let mutable storageAccount : CloudStorageAccount = null
static member Queue
with get() = queue
and set v = queue <- v
static member StorageAccount
with get() = storageAccount
and set v = storageAccount <- v
In another module, just:
open Common
Common.Queue <- xxxx

here is the convention used in F# PowerPack Matrix library (\src\FSharp.PowerPackmath\associations.fs):
// put global variable in a special module
module GlobalAssociations =
// global variable ht
let ht =
let ht = new System.Collections.Generic.Dictionary<Type,obj>()
let optab =
[ typeof<float>, (Some(FloatNumerics :> INumeric<float>) :> obj);
typeof<int32>, (Some(Int32Numerics :> INumeric<int32>) :> obj);
...
typeof<bignum>, (Some(BigRationalNumerics :> INumeric<bignum>) :> obj); ]
List.iter (fun (ty,ops) -> ht.Add(ty,ops)) optab;
ht
// method to update ht
let Put (ty: System.Type, d : obj) =
// lock it before changing
lock ht (fun () ->
if ht.ContainsKey(ty) then invalidArg "ty" ("the type "+ty.Name+" already has a registered numeric association");
ht.Add(ty, d))

Related

How to set a timercalling a member method in F#?

I am trying to achieve this:
type Test() =
member val MyTimer : Timer = new Timer(TimerCallback TimerEvent)
member mutable Status : bool = false
...
member this.StartTimer =
this.MyTimer....
member this.TimerEvent =
if this.Status...
I need to create a timer that is part of the class instance, needs to be referenced by several methods (to start / stop it) but also, the timer ballback needs to be able to access some of the inner states.
I can't find the syntax to create the timer object so that it has access to class members and class members have access to it.
But I think I'm having some confusion:
It looks like I can do the timer like this:
member this.Timer : Timer = new Timer(TimerCallback (fun x -> printfn "%A" x))
but I though member was reserved for methods and val for the fields? can anyone clarify this? I can do member this.xxx, but I can't do val this.xxx..
I found this post because I need to implement a scheduled job in F# for the first time.
I'm also learning F# and it is the first time I saw "val", so I read something about it.
Regarding your question.
"member val ... " is a particular case described here:
The val Kweyword
Another use of the val keyword is in conjunction with the member keyword to declare an auto-implemented property.
I think this answer your question.
Said that, I looked up to your code:
member this.Timer : Timer = new Timer(TimerCallback (fun x -> printfn "%A" x))
This is not correct to me because it exposes the Timer publicly.
I like the idea to have an object (the Timer) declared but not initialized, so that I can refer to its instance within multiple methods (Start/Stop) and (most important) Dispose it properly.
So, also regarding your doubt about the syntax...
I can't find the syntax to create the timer object so that it has access to class members and class members have access to it.
I came out with the following example:
open System
open System.Threading
type public ExampleJob () as me =
let timer_elapsed:TimerCallback = TimerCallback(fun (state) -> me.OnCall(state) )
[<DefaultValue>] val mutable private timer:Timer // no need to initialize
member __.IsActive with get() = __.timer <> null
member __.Start(frequency:TimeSpan) =
__.Stop() // Dispose previous timer if exists
__.timer <- new Timer(timer_elapsed)
__.timer.Change(0, int(frequency.TotalMilliseconds)) |> ignore
member __.Stop() =
if __.timer <> null then __.timer.Dispose() ; __.timer <- null
member private __.OnCall (state:obj) =
// do the real work here
// The state object is the Timer object.
Console.WriteLine(sprintf"OnCall(%i) at %s" ((state :?> Timer).GetHashCode()) (DateTime.Now.ToString("ss:fff")))
interface IDisposable with
member this.Dispose(): unit =
this.Stop()
Checking the Timer itself is enough to expose the Status (IsActive/IsRunning).
Start/Stop can be called in any sequence an number of times. A new call to Start() will reset the current timer to the new desired frequency.
It is not thread safe and I haven't tested it enough, so I'm not 100% sure the timer "survives" when/if the whole class is no more referenced.
Anyway I hope this is a useful example.
[Update]
new version with the suggestion of Ben
open System
type ExampleJob () =
let timer = new Timers.Timer()
let OnCall = fun(args) ->
// do real job here
Console.WriteLine(sprintf"OnCall(%O) at %s" args (DateTime.Now.ToString("ss:fff")))
do timer.Elapsed.Add(OnCall) // carefull to add it only once
member this.IsActive with get() = timer.Enabled
member this.Start(frequency:TimeSpan) =
timer.Interval <- frequency.TotalMilliseconds
timer.AutoReset <- true
timer.Enabled <- true
OnCall() // first call (if needed)
timer.Start()
member this.Stop() = timer.Enabled <- false
interface IDisposable with
member this.Dispose(): unit =
timer.Dispose()

Constructing and deconstructing records

The msdn page documenting Records (F#) details record expressions for record construction and record patterns for deconstruction, the latter without naming them as such.
Here's an example which uses both techniques for an arithmetic operator:
// Simple two-dimensional generic vector defintion
type 'a UV =
{ U : 'a; V : 'a }
static member inline (+) ({ U = au; V = av }, { U = bu; V = bv }) =
{ U = au + bu; V = av + bv }
This appears unwieldy and not very readable. For deconstruction, there are dot-notation or functions as alternatives. Since the dot-notation operator has a special dispensation in section 8.4.2 Name Resolution and Record Field Labels of the spec (an expression’s type may be inferred from a record label), there's normally no need to annotate. Accessor functions like let u { U = u } = u wouldn't give us any advantages then.
For construction, I think a case can be made for a function as record constructor. Access to the original constructor might even be restricted:
type 'a UV =
internal { U : 'a; V : 'a }
let uv u v = { U = u; V = v }
type 'a UV with
static member inline (+) (a, b) =
uv (a.U + b.U) (a.V + b.V)
Is this an idiomatic thing to do? How to package such functions in modules and handle namespace issues?
Short answer: I don't think there is a general convention here at the moment so it will be a personal decision in the end.
To summarise what you get for free with records in F# is:
Construct: { U = u; V = v } (bracket-notation)
Deconstruct: let u = record.u (dot-notation) and let {U = u} = record (pattern matching)
Update: {record with U = u} (bracket-notation)
But you don't get first class functions for free, if you want you can code them by hand.
The following is what I would personally use as convention:
A static member New with curried arguments for record construction.
For update and deconstruction I would use some kind of Lenses abstraction.
Here's an example of the code I would have to add by hand:
// Somewhere as a top level definition or in a base library
type Lens<'T,'U> = {Get: 'T -> 'U; Set: 'U -> 'T -> 'T } with
member l.Update f a = l.Set (f (l.Get a)) a
type UV<'a> = {U : 'a; V : 'a } with
// add these static members to your records
static member New u v : UV<'a> = {U = u; V = v}
static member u = {Get = (fun (x: UV<'a>) -> x.U); Set = fun t x -> {x with U = t}}
static member v = {Get = (fun (x: UV<'a>) -> x.V); Set = fun t x -> {x with V = t}}
let uvRecord = UV.New 10 20
let u = UV.u.Get uvRecord
let uvRecord1 = UV.u.Set (u+1) uvRecord
let uvRecord2 = UV.u.Update ((+)1) uvRecord
This way I would have first class functions for construction, deconstruction but also for updates plus other very interesting Lenses properties as you can read in this post.
UPDATE (in response to your comments)
Of course they can be defined later, what does it change?
The same applies for the New constructor, it can be defined later but that's actually a good thing.
The accessor functions you defined can also be defined later, indeed any first-class getter, setter or updater value can be defined later.
Anyway the answer to your question is "no, there are no conventions" the rest it's a personal decision, which would be my decision and also many Haskellers are pushing to get some kind of automatic Lenses for Haskell records.
Why would I decide to go this way? Because in terms of lines of code the effort of adding a simple accessor function is almost the same as adding a get-Lens, so for the same price I get more functionality.
If you are not happy with the Lenses discussion please tell me, I can delete it and leave the short answer, or I can delete the whole answer too if it's confusing instead of clarifying.
Or may be I misunderstood your question, for me your question was about which convention is generally used to add first-class constructors, getters and setters values for records.
Composition is not the only advantage of Lenses, you can do many things, keep reading about them, they provide a very interesting abstraction and not only restricted to records.

log4net style interface in F# -- static method returns instance of object

I'm trying to build a log4net style interface in an F# assembly. The key attribute is exposing a static method that returns an instance of an object. log4net makes use of C# delegates to accomplish the task, e.g. with LogManager.GetLogger("log123"). Delegates, from my understanding, are less favored than functions-as-first-class for inward-facing F# libraries.
The simplified code below accomplishes the objective, but I am uncomfortable with the use of an F# reference cell to hold a map of instantiated objects. I am interested in feedback on whether my discomfort is warranted.
namespace Test
[<Interface>]
type IMyIface =
abstract member Addi : int -> int
[<Sealed>]
type TheMainObject internal (x:int) =
let mutable sum = x
interface IMyIface with
member this.Addi(y:int) = sum <- sum + y; sum
module internal Wrapr =
let mymap = ref Map.empty
let mgr s =
let m = !mymap
if Map.containsKey s m then m.[s]
else
let x = new TheMainObject(0)
mymap := m.Add(s, x)
x
[<Sealed>]
type Mgr() =
static member Get(n:string) =
Wrapr.mgr n :> IMyIface
Program.fs calls the library above as follows:
open Test
let a = Mgr.Get("hello")
printfn "%d" (a.Addi(1))
let c = Mgr.Get("hello")
printfn "%d, %A" (c.Addi(3)) (a = c) //prints 4, true
Thanks in advance for comments.
It's OK to use a reference cell internally to hold a mutable value. You could also use a .Net Dictionary instead of a map. This is the approach I took while building a Mini IoC Container. If you expect the function accessing the reference cell to be called from multiple threads then you should probably use a lock or other thread synchronization.
There are a number of ways of exposing the Get method. The static member approach you have taken is useful if you expect to overload the method. In which case you may consider using static let for static locals over a separate module:
type [<Sealed>] Mgr() =
static let sync = obj()
static let lookup = Dictionary()
static let obtain name =
match lookup.TryGetValue(name) with
| true, x -> x
| false,_ ->
let x = TheMainObject(0)
lookup.Add(name,x)
x
static member Get(name:string) =
lock sync (fun () -> obtain name :> IMyIface)
If you do not expect to overload the Get function then you could just use a module:
module Mgr =
let private lookup = ref Map.empty
let private obtain name =
match (!lookup).TryFind name with
| Some(x) -> x
| None ->
let x = TheMainObject(0)
lookup := (!lookup).Add(name,x)
x
let Get name = obtain name :> IMyIface

How to create record with some local private functions in F#

type SQLConn =
val mutable private connection : string option
member this.Connection
with get() : string = this.connection.Value
and set(v) = this.connection <- Some v
new (connection : string) = {connection = Some connection;}
new() = SQLConn #"Data Source=D:\Projects\AL\Service\ncFlow\dbase\dbflow.db3; Version=3;Password=432432434324"
I want to use "let x = 5+5" there or something like that, so how can I use private functions in my type (class) (record) , I know that I can use them if I do SQLConn() , but then I can't use val, I want to use both : val and let ...
thank you
As Tim explains, you can only use local let bindings with the implicit constructor syntax. I would definitely follow this approach as it makes F# code more readable.
Do you have any particular reason why you also want to use val in your code? You can still use them with the implicit constructor syntax, but they have to be mutable and initialized using mutation:
type SQLConn(connection:string) as x =
let mutable connection = connection
// Declare field using 'val' declaration (has to be mutable)
[<DefaultValue>]
val mutable a : int
// Initialize the value imperatively in constructor
do x.a <- 10
member this.Connection
with get() = connection and set(v) = connection <- v
new() = SQLConn #"Data Source=.."
As far as I can tell val is only needed to create fields that are not private (which may be required by some code-gen based tools like ASP.NET, but is otherwise not really useful).
The error message explains the problem:
error FS0963: 'let' and 'do' bindings are not permitted in class definitions unless an implicit construction sequence is used. You can use an implicit construction sequence by modifying the type declaration to include arguments, e.g. 'type X(args) = ...'.
The error message is suggesting that you declare your class as type SQLConn(connection) =. If you do this, you probably ought to remove the member this.Connection property, since you'll no longer have a mutable field.
A more likely workaround would be to declare x as val x : int, then put the x = 5 + 5; initializer inside your constructor.
What about the following?
type SQLConn(conn:string) =
// could put some other let bindings here...
// ex: 'let y = 5 + 5' or whatever
let mutable conn = conn
new() = SQLConn(#"some default string")
member __.Connection
with get () = conn and set v = conn <- v

How to check if an event is being handled in F#

What is the F# equivalent of the following C# code? Specifically, I need to check if an event is being handled.
protected virtual void OnClicked(ClickEventArgs e) {
if (this.Clicked != null) //how can I perform this check in F#
this.Clicked(this, e);
}
Okay, I think I figured this thing out. Taking a cue from Don Syme's blog, specifically the section "The Implementation of the IEvent Module."
Instead of the following:
let validationFailedEvent = new Event<DataValidationEventHandler, DataValidationEventArgs>()
I had to implement IEvent myself and create a variable to hold the invocation list:
let mutable listeners: Delegate = null
let validationFailedEvent = { new IEvent<DataValidationEventHandler, DataValidationEventArgs> with
member x.AddHandler(d) =
listeners <- Delegate.Combine(listeners, d)
member x.RemoveHandler(d) =
listeners <- Delegate.Remove(listeners, d)
member x.Subscribe(observer) =
let h = new Handler<_>(fun sender args -> observer.OnNext(args))
(x :?> IEvent<_,_>).AddHandler(h)
{ new System.IDisposable with
member x.Dispose() = (x :?> IEvent<_,_>).RemoveHandler(h) } }
Then, to check if there are listeners, and, if not, raise an exception:
member private x.fireValidationFailedEvent(e:DataValidationEventArgs) =
match listeners with
| null -> failwith "No listeners"
| d -> d.DynamicInvoke([| box x; box e |])
An alternative way to implement RequiresSubscriptionEvent is to build on top of the existing Event functionality (using composition) and just add a counter that counts the number of registered handlers and add a property HasListeners (or even publish the number of listeners if you wanted...)
This makes the code a bit easier to use and hopefuly also safer, because if you don't check whether it has any listneres, it will still work as the usual F# code. And if you want to perform the check, you can...
type RequiresSubscriptionEvent<_>() =
let evt = new Event<_>()
let mutable counter = 0
let published =
{ new IEvent<_> with
member x.AddHandler(h) =
evt.Publish.AddHandler(h)
counter <- counter + 1;
member x.RemoveHandler(h) =
evt.Publish.RemoveHandler(h)
counter <- counter - 1;
member x.Subscribe(s) =
let h = new Handler<_>(fun _ -> s.OnNext)
x.AddHandler(h)
{ new System.IDisposable with
member y.Dispose() = x.RemoveHandler(h) } }
member x.Trigger(v) = evt.Trigger(v)
member x.Publish = published
member x.HasListeners = counter > 0
Sample usage:
type Demo() =
let evt = new RequiresSubscriptionEvent<_>()
[<CLIEvent>]
member x.OnSomething = evt.Publish
member x.FooThatFiresSomething() =
if evt.HasListeners then
evt.Trigger("foo!")
else
printfn "No handlers!"
Even though this isn't a part of standard F# libraries, it shows the great advantage of F# first class events. If there is some missing functionality, you can simply implement it yourself!
Typically, you don't need to do that check in F# (the event infrastructure checks for you):
type T() =
let ev = new Event<_>()
[<CLIEvent>]
member x.Event = ev.Publish
member x.OnClicked() =
ev.Trigger()
I followed kvb's suggestion and put this logic in a class. I copied Event from the F# sources and added a Handled property, which checks if the Delegate is null. I tried adding to, then removing handlers from the event to make sure it gets set back to null, and indeed it does.
type EventEx<'Delegate,'Args when 'Delegate : delegate<'Args,unit> and 'Delegate :> System.Delegate >() =
let mutable multicast : System.Delegate = null
static let argTypes =
let instanceBindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.DeclaredOnly
let mi = typeof<'Delegate>.GetMethod("Invoke",instanceBindingFlags)
mi.GetParameters() |> (fun arr -> arr.[1..]) |> Array.map (fun p -> p.ParameterType)
member x.Handled = (multicast <> null)
member x.Trigger(sender:obj,args:'Args) =
match multicast with
| null -> ()
| d ->
if argTypes.Length = 1 then
d.DynamicInvoke([| sender; box args |]) |> ignore
else
d.DynamicInvoke(Array.append [| sender |] (Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields(box args))) |> ignore
member x.Publish =
{ new IEvent<'Delegate,'Args> with
member x.AddHandler(d) =
multicast <- System.Delegate.Combine(multicast, d)
member x.RemoveHandler(d) =
multicast <- System.Delegate.Remove(multicast, d)
member e.Subscribe(observer) =
let h = new Handler<_>(fun sender args -> observer.OnNext(args))
(e :?> IEvent<_,_>).AddHandler(h)
{ new System.IDisposable with
member x.Dispose() = (e :?> IEvent<_,_>).RemoveHandler(h) } }
This article here http://geekswithblogs.net/Erik/archive/2008/05/22/122302.aspx says you do not need to check for null events in F#, though I don't know what his reference is.
This article http://blogs.msdn.com/dsyme/articles/FSharpCompositionalEvents.aspx by Don Symes goes into F# events in quite a bit of detail. It looks like events are not owned by the class in F#
From the above,
it is that events are now first-class
values in the F# langauge. Indeed,
events are not a separate notion at
all in the language design, rather,
events are just values of type
Microsoft.FSharp.Idioms.IEvent<_>, and
.NET events are effectively just
properties of this type.
And
One of the restrictions of C# is that
events can only exist as members
within classes. With the F# model,
new event values can be created just
as values as part of any expression.

Resources