Can an object expression refer to itself? - f#

I'm exploring converting our C# codebase to F#. This codebase uses an external library that provides an interface; one of the methods allows the library to create new instances of our class:
public class Worker : IWorker
{
public IWorker CreateNewInstance()
{
return new Worker();
}
}
Given the number of these classes, I'd like to take advantage of object expressions. Is there a way an object expression can refer to itself in this way?

I'm not sure I would recommend this without knowing more about your use case, but something like this should work:
let rec makeWorker () =
{
new IWorker with
member _.CreateNewInstance() = makeWorker ()
}
let worker1 = makeWorker ()
let worker2 = worker1.CreateNewInstance()

Related

Dart - Instantiate Generic Type by Mapping Constructors

You cannot instantiate a generic type in Dart and you cannot use mirrors in Flutter. However, you can map types to their constructors in a closure.
This could be useful for something like JSON serialization when working with handwritten classes, especially if the data source returns the same data shape in many forms, i.e Future<T> or Stream<T>.
Question: Is this a valid pattern and are there any potential drawbacks? Better alternatives?
class Dog{}
class Cat{}
Map models = {
Dog: () => Dog(),
Cat: () => Cat()
};
class Database<T> {
T data;
Database() {
data = models[T](); // <-- this feels a bit weird, but works
}
}
void main() {
Database<Cat> cat = Database();
print(cat.data is Cat);
}

Difference between class-level and member-level self-identifier in F#?

Is there any semantic difference between class-level and member-level self-identifiers in F#? For example, consider this class:
type MyClass2(dataIn) as self =
let data = dataIn
do
self.PrintMessage()
member this.Data = data
member this.PrintMessage() =
printfn "Creating MyClass2 with Data %d" this.Data
Versus this class:
type MyClass2(dataIn) as self =
let data = dataIn
do
self.PrintMessage()
member this.Data = data
member this.PrintMessage() =
printfn "Creating MyClass2 with Data %d" self.Data
The only difference is that the implementation of PrintMessage references this in one vs. self in the other. Is there any difference in semantics? If not, is there a stylistic reason to prefer one over the other?
There's no real semantic difference between the two. As a rule of thumb, I suggest going with your first example - prefer the identifier that's closer in scope, it makes it easier to read and refactor the code later. As a side note, people will usually use this both for class and member-level identifiers, in which case the member-level one shadows class-level one.
In these kind of scenarios, it's useful to look at the compiled code in a disassembler like ILSpy. If you do that, you'll find that the only difference is an extra null check that is inserted in self.Data case.
On the other hand, there is a difference between a class that uses a class-level identifier and one that doesn't (a series of initialization checks get inserted into all the class members). It's best to avoid having them if possible, and your example can be rewritten to not require one.
As mentioned by scrwtp, this seems to be a commonly used identifier and it is my preference. Another very common one is x. I tend to use the class-level identifier when it's used multiple times throughout a class and of course when it's used in the constructor. And in those cases I would use __ (two underscores) as the member level identifier, to signify that the value is ignored. You can't use _ and actually ignore it as it's a compile error, but linting tools will often consider __ as the same thing and avoid giving you a warning about an unused identifier.
When you add a class-level identifier and don't use it you get a warning:
The recursive object reference 'self' is unused. The presence of a recursive object reference adds runtime initialization checks to members in this and derived types. Consider removing this recursive object reference.
Consider this code:
type MyClass() =
member self.X = self
type MyClassAsSelf() as self =
member __.X = self
type MyClassAsSelfUnused() as self = // <-- warning here
member __.X = ()
This is what these classes look like after compiling/decompiling:
public class MyClass
{
public Program.MyClass X
{
get
{
return this;
}
}
public MyClass() : this()
{
}
}
public class MyClassAsSelf
{
internal FSharpRef<Program.MyClassAsSelf> self = new FSharpRef<Program.MyClassAsSelf>(null);
internal int init#22;
public Program.MyClassAsSelf X
{
get
{
if (this.init#22 < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
return LanguagePrimitives.IntrinsicFunctions.CheckThis<Program.MyClassAsSelf>(this.self.contents);
}
}
public MyClassAsSelf()
{
FSharpRef<Program.MyClassAsSelf> self = this.self;
this..ctor();
this.self.contents = this;
this.init#22 = 1;
}
}
public class MyClassAsSelfUnused
{
internal int init#25-1;
public Unit X
{
get
{
if (this.init#25-1 < 1)
{
LanguagePrimitives.IntrinsicFunctions.FailInit();
}
}
}
public MyClassAsSelfUnused()
{
FSharpRef<Program.MyClassAsSelfUnused> self = new FSharpRef<Program.MyClassAsSelfUnused>(null);
FSharpRef<Program.MyClassAsSelfUnused> self2 = self2;
this..ctor();
self.contents = this;
this.init#25-1 = 1;
}
}
Note that there is a check that a variable has been set in the constructor. If the check fails then a function is called: LanguagePrimitives.IntrinsicFunctions.FailInit(). This is the exception thrown:
System.InvalidOperationException: The initialization of an object or value resulted in an object or value being accessed recursively before it was fully initialized.
I guess the warning is there just so that you can avoid the slight overhead of an unnecessary runtime check. However, I don't know how to construct a situation where the error is thrown, so I don't know the exact purpose of the check. Perhaps someone else can shed light on this?

How to inherit the same generic interface twice with different types in F# 3.0 [duplicate]

In C#, I can implement a generic interface twice on one class, using two different type-parameters:
interface IFoo<T> { void Foo(T x); }
class Bar : IFoo<int>, IFoo<float>
{
public void Foo(int x) { }
public void Foo(float y) { }
}
I would like to do the same thing in F#:
type IFoo<'a> = abstract member Foo : 'a -> unit
type Bar() =
interface IFoo<int> with
[<OverloadID("int")>]
member this.Foo x = ()
interface IFoo<float> with
[<OverloadID("float")>]
member this.Foo x = ()
But it gives a compiler error:
This type implements or inherits the same interface at different generic instantiations 'IFoo<float>' and 'IFoo<int>'. This is not permitted in this version of F#.
I can't find any discussion of this issue on the web. Is such use frowned upon for some reason? Are there plans to allow this in an upcoming release of F#?
Right now I don't know of plans to allow this.. The feature has been planned and is, at least partially (see comments) implemented in F# 4.0.
I think the only reasons its currently disallowed are that it's non-trivial to implement (especially with F# type inference), and it rarely arises in practice (I only recall one customer ever asking about this).
Given an infinite amount of time and resources, I think this would be allowed (I can imagine this being added to a future version of the language), but right now it does not seem like this is a feature worth the effort of supporting. (If you know a strong motivating case, please mail fsbugs#microsoft.com.)
EDIT
As an experiment for the curious, I wrote this C#:
public interface IG<T>
{
void F(T x);
}
public class CIG : IG<int>, IG<string>
{
public void F(int x) { Console.WriteLine("int"); }
public void F(string x) { Console.WriteLine("str"); }
}
and referenced it from F# (with comments suggesting the results)
let cig = new CIG()
let idunno = cig :> IG<_> // type IG<int>, guess just picks 'first' interface?
let ii = cig :> IG<int> // works
ii.F(42) // prints "int"
let is = cig :> IG<string> // works
is.F("foo") // prints "str"
so this is what typically happens on this 'boundary' stuff with F# - F# can consume this stuff ok, even if you can't author the same stuff from within the language.
There is a reasonable although not elegant way to do it, create a new type for each interface here is an example of consuming multiple events from an ESB (nSvcBus) which requires that each event corresponds to an implemented interface. The first type below contains the generic 'handler' code, the other types just implement the interface and call to the generic handler
type public nSvcBusEvents() =
member this.HandleEvents(msg:IEvent) = ()
//handle messages ie: let json = JsonConvert.SerializeObject(msg)
type public ActionLoggedHandler() =
interface IHandleMessages<Events.ActionLoggedEvent> with
member this.Handle(msg : ActionLoggedEvent) =
nSvcBusEvents().HandleEvents(msg)
type public ActionCompletedHandler() =
interface IHandleMessages<Events.ActionCompletedHandler> with
member this.Handle(msg : ActionCompletedHandler) =
nSvcBusEvents().HandleEvents(msg)
type public ActionFailedHandler() =
interface IHandleMessages<Events.ActionFailedHandler> with
member this.Handle(msg : ActionFailedHandler) =
nSvcBusEvents().HandleEvents(msg)

Ninject binds to the wrong anonymous method when there is more than one method bound type

I am building a framework that I don't want to couple to a particular IOC container so have created a layer on top of Ninject / structuremap etc.
I have a binding class that accepts a Func to allow binding to a method.
For example
public class Binding
{
public Type Source { get; set; }
public Func<object> Method {get; set; }
public Scope { get; set; }
}
If I have a binding like...
var binding = new Binding() {
Source = typeof(IRepository),
Method = () => new Repository(new LinqToSqlRepository(connectionString)),
Scope = Scope.HttpRequest
};
The framework wrapping Ninject creates Ninject bindings for my generic binding like this
Module :NinjectModule
{
IList<Binding> _Bindings;
public Module(IList<Binding> bindings)
{
_Bindings = bindings;
}
public override void Load() {
foreach (var binding in _Bindings) {
switch(binding.Scope) {
case IocScope.HttpRequest:
Bind(binding.Source).ToMethod(c => binding.Method()).InRequestScope();
break;
// ... omitted for brevity
}
}
}
}
This works fine when there is only one binding being bound to a method. When there are multiple bindings being bound within the same module to methods however the incorrect type is returned. From debugging, it looks as if the last binding is always used.
Thus the problem with an example;
var binding1 = new Binding() {
Source = typeof(IRepository),
Method = () => new Repository(new LinqToSqlRepository(connectionString)),
Scope = Scope.HttpRequest
};
var binding2 = new Binding() {
Source = typeof(ICalendar),
Method = () => new MvcCalendar( ..... )
Scope = Scope.HttpRequest
};
At runtime when Ninject is requested to new up an MVC Controller which takes in an IRepository and an ICalendar, I receive a type conversion error saying that a MvcCalendar cannot be converted to an IRepository. I have discovered that for some reason the last binding is always being returned for the first requested type.
This is a highly simplified version of what is really going on to try and highlight the actual issue, the wrong method being bound to a requested type when there are multiple method bindings. I hope this still explains the issue though.
This appears to be related to some sort of closure scoping issue. I also wonder whether Ninject is getting is getting confused by the Func instead of Func usage.
Unit Test Example
Here is a test module I load into my custom IOC container. This does not depend on any particular IOC framework. When I instantiate a NinjectIocContainer to handle the DI, the internal binding of this in Ninject occurs as example further up (see NinjectModule)
public class MultipleMethodBoundTypesModule : IocModule
{
public override void Load()
{
Bind<IPerson>().To(() => new Person()).In(IocScope.Transient);
Bind<IRobot>().To(() => new Robot(new Person())).In(IocScope.Transient);
}
}
Here is a simple test that tries to retrieve each of the types.
[Test]
public void Expect_That_Multiple_Method_Bound_Types_Can_Exist_Within_The_Same_Module()
{
// arrange
var container = Get_Container_With_Module(new MultipleMethodBoundTypesModule());
// act
var person = container.Get<IPerson>();
var robot = container.Get<IRobot>();
// assert
Assert.IsNotNull(person);
Assert.IsNotNull(robot);
}
As explained eariler, this throws a type conversion where the last closure (for the robot) is being bound to a person.
TestCase 'Ioc.Test.NinjectContainerTest.Expect_That_Multiple_Method_Bound_Types_Can_Exist_Within_The_Same_Module'
failed: System.InvalidCastException : Unable to cast object of type 'Ioc.Test.Robot' to type 'Ioc.Test.IPerson'.
at System.Linq.Enumerable.d__b11.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable1 source)
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
NinjectIocContainer.cs(40,0): at Ioc.Ninject.NinjectIocContainer.GetTInstance
IocTestBase.cs(149,0): at Ioc.Test.IocTestBase.Expect_That_Multiple_Method_Bound_Types_Can_Exist_Within_The_Same_Module()
In the snippet:
Bind(binding.Source).ToMethod(binding.Method()).InRequestScope();
You're dereferencing the Method bit. You want to be doing that as either binding.Method or ()=>binding.Method() (the former may not unambiguously be inferrable based on the C# type inference rules).
You mentioned this is heavily stripped down from your real code. As a result, this may not be the actual issue. I'd still be betting on some form of closure confusion though (see the section Comparing capture strategies: complexity vs power in this CSID excerpt for a nice walkthrough).
You also probably meant to use .InScope(binding.Scope) rather than .InRequestScope() too,.

Implementing the same interface at different generic instantiations

In C#, I can implement a generic interface twice on one class, using two different type-parameters:
interface IFoo<T> { void Foo(T x); }
class Bar : IFoo<int>, IFoo<float>
{
public void Foo(int x) { }
public void Foo(float y) { }
}
I would like to do the same thing in F#:
type IFoo<'a> = abstract member Foo : 'a -> unit
type Bar() =
interface IFoo<int> with
[<OverloadID("int")>]
member this.Foo x = ()
interface IFoo<float> with
[<OverloadID("float")>]
member this.Foo x = ()
But it gives a compiler error:
This type implements or inherits the same interface at different generic instantiations 'IFoo<float>' and 'IFoo<int>'. This is not permitted in this version of F#.
I can't find any discussion of this issue on the web. Is such use frowned upon for some reason? Are there plans to allow this in an upcoming release of F#?
Right now I don't know of plans to allow this.. The feature has been planned and is, at least partially (see comments) implemented in F# 4.0.
I think the only reasons its currently disallowed are that it's non-trivial to implement (especially with F# type inference), and it rarely arises in practice (I only recall one customer ever asking about this).
Given an infinite amount of time and resources, I think this would be allowed (I can imagine this being added to a future version of the language), but right now it does not seem like this is a feature worth the effort of supporting. (If you know a strong motivating case, please mail fsbugs#microsoft.com.)
EDIT
As an experiment for the curious, I wrote this C#:
public interface IG<T>
{
void F(T x);
}
public class CIG : IG<int>, IG<string>
{
public void F(int x) { Console.WriteLine("int"); }
public void F(string x) { Console.WriteLine("str"); }
}
and referenced it from F# (with comments suggesting the results)
let cig = new CIG()
let idunno = cig :> IG<_> // type IG<int>, guess just picks 'first' interface?
let ii = cig :> IG<int> // works
ii.F(42) // prints "int"
let is = cig :> IG<string> // works
is.F("foo") // prints "str"
so this is what typically happens on this 'boundary' stuff with F# - F# can consume this stuff ok, even if you can't author the same stuff from within the language.
There is a reasonable although not elegant way to do it, create a new type for each interface here is an example of consuming multiple events from an ESB (nSvcBus) which requires that each event corresponds to an implemented interface. The first type below contains the generic 'handler' code, the other types just implement the interface and call to the generic handler
type public nSvcBusEvents() =
member this.HandleEvents(msg:IEvent) = ()
//handle messages ie: let json = JsonConvert.SerializeObject(msg)
type public ActionLoggedHandler() =
interface IHandleMessages<Events.ActionLoggedEvent> with
member this.Handle(msg : ActionLoggedEvent) =
nSvcBusEvents().HandleEvents(msg)
type public ActionCompletedHandler() =
interface IHandleMessages<Events.ActionCompletedHandler> with
member this.Handle(msg : ActionCompletedHandler) =
nSvcBusEvents().HandleEvents(msg)
type public ActionFailedHandler() =
interface IHandleMessages<Events.ActionFailedHandler> with
member this.Handle(msg : ActionFailedHandler) =
nSvcBusEvents().HandleEvents(msg)

Resources