F# constructor syntax - overiding and augmenting new - syntax

I have a non-disposable class with Open/Close syntax that I'd like to be able to use, so I'm trying to inherit from it, and work the Open into the new and the Close into Dispose.
The second part is ok, but I can't work out how to do the Open:
type DisposableOpenCloseClass(openargs) =
inherit OpenCloseClass()
//do this.Open(openargs) <-- compiler no like
interface IDisposable
with member this.Dispose() = this.Close()
(cf. this question which I asked a long time ago, but I can't join the dots to this one)

Key is as this:
type OpenCloseClass() =
member this.Open(x) = printfn "opened %d" x
member this.Close() = printfn "closed"
open System
type DisposableOpenCloseClass(openargs) as this =
inherit OpenCloseClass()
do this.Open(openargs)
interface IDisposable
with member this.Dispose() = this.Close()
let f() =
use docc = new DisposableOpenCloseClass(42)
printfn "inside"
f()

As Brian suggests, you can use the as this clause. However, in F#, it is usually recomended to use subclassing (inheritance) only when there is a really good reason for that (e.g. you need to implement some virtual class and pass it to a .NET library).
If I was implementing your example, I would probably prefer function returning IDisposable using a simple object expression:
let disposableOpenClose(openargs) =
let oc = new OpenCloseClass()
oc.Open(openargs)
{ new IDisposable with
member this.Dispose() = oc.Close() }
let f() =
use docc = disposableOpenClose(42)
printfn "inside"
To some point, this is just a personal preference, but I think it is a preferred option, because it is simpler than using inheritance (although I don't have any document to link here :-)). Also, the compiled code may be a bit simpler, because handling as this may require some runtime checks.

Related

GUI update patterns in F#

I'm looking for the best way to propagate model updates to the GUI, using a "classic" (as in: non reactive functional) GUI toolkit: Terminal.GUI. Currently I have this code (simplified):
type Tui(state: StateManager) =
let state = state
let window = Window(bla bla bla)
let lblPath = Label(bla bla bla)
let lstView =
{ new ListView(bla bla bla) with
member this.ProcessKey(k: KeyEvent) =
let updateViews() =
Application.MainLoop.Invoke(fun () ->
this.SetSource model.CurrentState.LstData
lblPath.Text <- ustr model.CurrentState.CurrPath)
match k.Key with
| Key.CursorRight ->
state.changeTheState()
updateViews()
true
| _ -> true }
do
Application.Init()
// add all GUI components: window.add(lblPath), etc
Application.Run()
// XXX repetition of updateViews() above!
Application.MainLoop.Invoke(fun () ->
lstView.SetSource model.CurrentState.LstData
lblPath.Text <- ustr model.CurrentState.CurrPath)
The issue here is that the code to update the view components is duplicated. I believe this is because:
in that ProcessKey method of the ListView object expression I cannot access any external method of the Tui class (this is probably also because F# compiler is one-pass only (?))
outside that method I cannot access the updateView function
Is there a better way of doing this that would avoid code repetition? Am I using the wrong pattern GUI update pattern?
(Complete code is here)
Of course, it doesn't need to be too complicated - refactor your update to just take in a listview parameter:
let updateViews (lstView: ListView) =
Application.MainLoop.Invoke(fun () ->
lstView.SetSource state.CurrentState.LstData
...
)
And inside the member definition, call:
updateViews(this)
And below, you can use updateViews lstView.
When you use an object expression, the type of the expression becomes the type you specify in new <type>, so any type augmentations you do inside won't make it outside. For a more OOP approach, declare an intermediate type:
[<AbstractClass>]
type UpdateableList() =
inherit ListView([||])
abstract member Update: unit -> unit
implement your update logic:
{ new UpdateableList(X = Pos.At(0), Y = Pos.At(2), ...) with
member this.Update() =
...
and in your setup, you have access to a public method:
lstView.Update()

Functional programming and dependency inversion: how to abstract storage?

I'm trying to create a solution that has a lower-level library that will know that it needs to save and load data when certain commands are called, but the implementation of the save and load functions will be provided in a platform-specific project which references the lower-level library.
I have some models, such as:
type User = { UserID: UserID
Situations: SituationID list }
type Situation = { SituationID: SituationID }
And what I want to do is be able to define and call functions such as:
do saveUser ()
let user = loadUser (UserID 57)
Is there any way to define this cleanly in the functional idiom, preferably while avoiding mutable state (which shouldn't be necessary anyway)?
One way to do it might look something like this:
type IStorage = {
saveUser: User->unit;
loadUser: UserID->User }
module Storage =
// initialize save/load functions to "not yet implemented"
let mutable storage = {
saveUser = failwith "nyi";
loadUser = failwith "nyi" }
// ....elsewhere:
do Storage.storage = { a real implementation of IStorage }
do Storage.storage.saveUser ()
let user = Storage.storage.loadUser (UserID 57)
And there are variations on this, but all the ones I can think of involve some kind of uninitialized state. (In Xamarin, there's also DependencyService, but that is itself a dependency I would like to avoid.)
Is there any way to write code that calls a storage function, which hasn't been implemented yet, and then implement it, WITHOUT using mutable state?
(Note: this question is not about storage itself -- that's just the example I'm using. It's about how to inject functions without using unnecessary mutable state.)
Other answers here will perhaps educate you on how to implement the IO monad in F#, which is certainly an option. In F#, though, I'd often just compose functions with other functions. You don't have to define an 'interface' or any particular type in order to do this.
Develop your system from the Outside-In, and define your high-level functions by focusing on the behaviour they need to implement. Make them higher-order functions by passing in dependencies as arguments.
Need to query a data store? Pass in a loadUser argument. Need to save the user? Pass in a saveUser argument:
let myHighLevelFunction loadUser saveUser (userId) =
let user = loadUser (UserId userId)
match user with
| Some u ->
let u' = doSomethingInterestingWith u
saveUser u'
| None -> ()
The loadUser argument is inferred to be of type User -> User option, and saveUser as User -> unit, because doSomethingInterestingWith is a function of type User -> User.
You can now 'implement' loadUser and saveUser by writing functions that call into the lower-level library.
The typical reaction I get to this approach is: That'll require me to pass in too many arguments to my function!
Indeed, if that happens, consider if that isn't a smell that the function is attempting to do too much.
Since the Dependency Inversion Principle is mentioned in the title of this question, I'd like to point out that the SOLID principles work best if all of them are applied in concert. The Interface Segregation Principle says that interfaces should be as small as possible, and you don't get them smaller than when each 'interface' is a single function.
For a more detailed article describing this technique, you can read my Type-Driven Development article.
You can abstract storage behind interface IStorage. I think that was your intention.
type IStorage =
abstract member LoadUser : UserID -> User
abstract member SaveUser : User -> unit
module Storage =
let noStorage =
{ new IStorage with
member x.LoadUser _ -> failwith "not implemented"
member x.SaveUser _ -> failwith "not implemented"
}
In another part of your program you can have multiple storage implementations.
type MyStorage() =
interface IStorage with
member x.LoadUser uid -> ...
member x.SaveUser u -> ...
And after you have all your types defined you can decide which to use.
let storageSystem =
if today.IsShinyDay
then MyStorage() :> IStorage
else Storage.noStorage
let user = storageSystem.LoadUser userID

F# Downcasting Slow?

I have a situation where I need to downcast twice in one procedure using :?>. I have a custom EventArgs class (which inherits System.EventArgs), and an instance of an abstract class within that custom EventArgs. Upon receiving the event, I need to downcast twice. Once for the custom EventArgs, and once for the abstract class within that custom EventArgs. I have to do this potentially millions of times a day, so I'm wondering if there's anything inherently slow about downcasting.
For grins, I put together the following little function:
let castToStream (o:Object) = o :?> Stream
and called it with the following code:
[<EntryPoint>]
let main argv =
let stm1 = new FileStream("output.tmp", FileMode.Create, FileAccess.ReadWrite, FileShare.Read)
let obj = stm1 :> Object
let stm2 = castToStream obj
0 // return an integer exit code
When it is compiled, castToStream turns into this IL:
.method public static class [mscorlib]System.IO.Stream
castToStream(object o) cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: unbox.any [mscorlib]System.IO.Stream
IL_0007: ret
} // end of method Program::castToStream
which in this case is effectively 1 real instruction, unbox.any. Unbox.any for a reference type is equivalent to a castclass instruction. From the description, you'll take a one-time initial hit to load the type if it's not already loaded, then it's going to be a whatever magic is necessary to determine if the types are equivalent (likely using Type.IsAssignableFrom(), but I don't know for sure). However, unless your class hierarchy is super deep (and it shouldn't be), I would expect this to take microseconds on a typical machine.
For the curious, I initially had the code for castToStream inline, but the f# compiler saw through my shenanigans and removed all the casting entirely.

Event.create in f#?

I'm trying to compile the source code from : Custom WPF Controls in F#
How ever this line :
let (handler, event) = Event.create<EventArgs>()
raises an error :
The value, constructor, namespace or type 'create' is not defined
The MSDN's Control.Event Module (F#) page does speak about such a function :
The additional functionality provided by the Event module is
illustrated here. The following code example illustrates the basic use
of Event.create to create an event and a trigger method, add two
event handlers in the form of lambda expressions, and then trigger the
event to execute both lambda expressions.
type MyType() =
let myEvent = new Event<_>()
member this.AddHandlers() =
Event.add (fun string1 -> printfn "%s" string1) myEvent.Publish
Event.add (fun string1 -> printfn "Given a value: %s" string1) myEvent.Publish
member this.Trigger(message) =
myEvent.Trigger(message)
let myMyType = MyType()
myMyType.AddHandlers()
myMyType.Trigger("Event occurred.")
However note that it's only mentionned in the description, not in the example.
Also, the Control.Event Module (F#) page has no reference to such a create function.
I guess it might be an old function or something, but I'm new to F# so I can't see what it should be replaced with..
Event.create is a fairly old API for events, from before F# 2.0 judging by what's on MSDN. It gave you a trigger function and a published event - both of which now live as Publish and Trigger members of Event class.
So if you wanted to implement create in the 'modern' terms, it might look somewhat like this:
module Event =
let create<'T> () =
let event = Event<'T>()
event.Trigger, event.Publish
I don't suggest you use it universally, but perhaps that's good enough to bring that old code back to life (the correct approach here being refactoring it to use Publish and Trigger instead of create).

What's so great about Func<> delegate?

Sorry if this is basic but I was trying to pick up on .Net 3.5.
Question: Is there anything great about Func<> and it's 5 overloads? From the looks of it, I can still create a similar delgate on my own say, MyFunc<> with the exact 5 overloads and even more.
eg: public delegate TResult MyFunc<TResult>() and a combo of various overloads...
The thought came up as I was trying to understand Func<> delegates and hit upon the following scenario:
Func<int,int> myDelegate = (y) => IsComposite(10);
This implies a delegate with one parameter of type int and a return type of type int. There are five variations (if you look at the overloads through intellisense). So I am guessing that we can have a delegate with no return type?
So am I justified in saying that Func<> is nothing great and just an example in the .Net framework that we can use and if needed, create custom "func<>" delegates to suit our own needs?
Thanks,
The greatness lies in establishing shared language for better communication.
Instead of defining your own delegate types for the same thing (delegate explosion), use the ones provided by the framework. Anyone reading your code instantly grasps what you are trying to accomplish.. minimizes the time to 'what is this piece of code actually doing?'
So as soon as I see a
Action = some method that just does something and returns no output
Comparison = some method that compares two objects of the same type and returns an int to indicate order
Converter = transforms Obj A into equivalent Obj B
EventHandler = response/handler to an event raised by some object given some input in the form of an event argument
Func = some method that takes some parameters, computes something and returns a result
Predicate = evaluate input object against some criteria and return pass/fail status as bool
I don't have to dig deeper than that unless it is my immediate area of concern. So if you feel the delegate you need fits one of these needs, use them before rolling your own.
Disclaimer: Personally I like this move by the language designers.
Counter-argument : Sometimes defining your delegate may help communicate intent better. e.g. System.Threading.ThreadStart over System.Action. So it’s a judgment call in the end.
The Func family of delegates (and their return-type-less cousins, Action) are not any greater than anything else you'd find in the .NET framework. They're just there for re-use so you don't have to redefine them. They have type parameters to keep things generic. E.g., a Func<T0,bool> is the same as a System.Predicate<T> delegate. They were originally designed for LINQ.
You should be able to just use the built-in Func delegate for any value-returning method that accepts up to 4 arguments instead of defining your own delegate for such a purpose unless you want the name to reflect your intention, which is cool.
Cases where you would absolutely need to define your delegate types include methods that accept more than 4 arguments, methods with out, ref, or params parameters, or recursive method signatures (e.g., delegate Foo Foo(Foo f)).
In addition to Marxidad's correct answer:
It's worth being aware of Func's related family, the Action delegates. Again, these are types overloaded by the number of type parameters, but declared to return void.
If you want to use Func/Action in a .NET 2.0 project but with a simple route to upgrading later on, you can cut and paste the declarations from my version comparison page. If you declare them in the System namespace then you'll be able to upgrade just by removing the declarations later - but then you won't be able to (easily) build the same code in .NET 3.5 without removing the declarations.
Decoupling dependencies and unholy tie-ups is one singular thing that makes it great. Everything else one can debate and claim to be doable in some home-grown way.
I've been refactoring slightly more complex system with an old and heavy lib and got blocked on not being able to break compile time dependency - because of the named delegate lurking on "the other side". All assembly loading and reflection didn't help - compiler would refuse to just cast a delegate() {...} to object and whatever you do to pacify it would fail on the other side.
Delegate type comparison which is structural at compile time turns nominal after that (loading, invoking). That may seem OK while you are thinking in terms of "my darling lib is going to be used forever and by everyone" but it doesn't scale to even slightly more complex systems. Fun<> templates bring a degree of structural equivalence back into the world of nominal typing . That's the aspect you can't achieve by rolling out your own.
Example - converting:
class Session (
public delegate string CleanBody(); // tying you up and you don't see it :-)
public static void Execute(string name, string q, CleanBody body) ...
to:
public static void Execute(string name, string q, Func<string> body)
Allows completely independent code to do reflection invocation like:
Type type = Type.GetType("Bla.Session, FooSessionDll", true);
MethodInfo methodInfo = type.GetMethod("Execute");
Func<string> d = delegate() { .....} // see Ma - no tie-ups :-)
Object [] params = { "foo", "bar", d};
methodInfo.Invoke("Trial Execution :-)", params);
Existing code doesn't notice the difference, new code doesn't get dependence - peace on Earth :-)
One thing I like about delegates is that they let me declare methods within methods like so, this is handy when you want to reuse a piece of code but you only need it within that method. Since the purpose here is to limit the scope as much as possible Func<> comes in handy.
For example:
string FormatName(string pFirstName, string pLastName) {
Func<string, string> MakeFirstUpper = (pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
};
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
It's even easier and more handy when you can use inference, which you can if you create a helper function like so:
Func<T, TReturn> Lambda<T, TReturn>(Func<T, TReturn> pFunc) {
return pFunc;
}
Now I can rewrite my function without the Func<>:
string FormatName(string pFirstName, string pLastName) {
var MakeFirstUpper = Lambda((string pText) => {
return pText.Substring(0,1).ToUpper() + pText.Substring(1);
});
return MakeFirstUpper(pFirstName) + " " + MakeFirstUpper(pLastName);
}
Here's the code to test the method:
Console.WriteLine(FormatName("luis", "perez"));
Though it is an old thread I had to add that func<> and action<> also help us use covariance and contra variance.
http://msdn.microsoft.com/en-us/library/dd465122.aspx

Resources