Idiomatic F# for "only once" post-initialization mutation? - f#

In the following, the way I define Animator is common in OOP systems, where it is considered fine to mutate this object's state:
type MyViewController() =
inherit UIViewController()
//Is there a better way than this?
member val Animator = null with get, set
override this.ViewDidLoad() =
base.ViewDidLoad()
//this.View is defined in base class and is only valid *now*
this.Animator <- new UIDynamicAnimator(this.View)
Is there a more idiomatic way to define Animator that communicates: "null->object is ok, object -> object is forbidden"?
(Obviously, I could write a custom set function that checks and throws at runtime, but that seems more annoyingly "clever" than helpful.)

Once the library depends so heavily on inheritance, it is really hard to avoid the usual OO patterns, even when you're using F#. So to be fair, I would probably write exactly the same code you did and just live with the fact that this part of the code is not going to be that pretty (and use more functional approach in the parts of the application where you're not forced into OO style by the framework).
Also, in this case, I'd just live with the null - you can use option, but you're not getting any benefits, because you cannot do much if the value is None anyway.
Presumably, in your full source code, you are overriding other methods of the class and you are creating Animator so that it can be used in the other methods. One thing you could do is to extract the code from the class and write something like this:
type IInitializedView =
abstract OtherMethod : UIViewController -> unit
type MyViewController(viewInitialized:UIView -> IInitializedView) =
inherit UIViewController()
let mutable initializedView = None
override this.ViewDidLoad() =
base.ViewDidLoad()
initializedView := Some(viewInitialized this.View)
override this.OtherMethod() =
viewInitialized |> Option.iter (fun vi ->
vi.OtherMethod() )
The idea here is that MyViewController calls your function when it has view and your function then creates a new interface that handles the other method - but your interface is created only after everything is properly initialized!
let vc = MyViewController(fun view ->
// Now we have valid 'view' so we construct animator!
let animator = UIDynamicAnimator(view)
{ new IInitializedView with
member x.OtherMethod() =
// no problem here, because we have animator...
animator.Whatever() })
But I don't know enough about Xamarin to say whether this would work OK in a full more complex system.

I think what #Carsten gets at is that you shouldn't introduce null values unless you are absolutely forced to by interop with other CLI languages. Types declared in F# wouldn't allow them anyway, unless decorated with an AllowNullLiteralAttribute.
The value wrapped in the Option<'a> type would be a somewhat direct translation, but still has mutability. I'm assuming that you do not really need the property setter, replacing the automatic property with a let-bound value.
type MyViewController() =
inherit UIViewController()
let mutable animator = Option<UIDynamicAnimator>.None
member x.Animator = animator.Value
override this.ViewDidLoad() =
base.ViewDidLoad()
animator <- Some <| new UIDynamicAnimator(this.View)
On the other hand, wrapping in Lazy<'a> is a little bit more in the functional spirit.
type MyViewController() as this =
inherit UIViewController()
let animator = lazy(new UIDynamicAnimator(this.View))
member x.Animator = animator.Value
override this.ViewDidLoad() =
base.ViewDidLoad()
// Optional; only if you need the object creation right now
animator.Force() |> ignore

Related

Is there a tangible benefit to using "self" outside of closures?

I have noticed a few people in the industry will use the self keyword even when not explicitly required (i.e. outside of closures).
Example:
import UIKit
import MapView
import CoreLocation
class viewController: UIViewController, MKMapViewDelegate, CLLocationDelegate {
let mapView = MKMapView()
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.delegate = self
self.mapView.showsUserLocation = true
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
}
Is there a tangible benefit to this, runtime-wise? Or is this purely a stylistic choice?
There is.
In the examples you provided it makes no difference, it's purely a style choice. Some people might like it since it explicitly tells you you're modifying self, personally I think it looks cleaner without.
Where it matters is when you have a local variable with the same name. Let's say you have a class that has a var count: Int property. Then, in one of your methods, you declare a new variable with the same name.
The local variable will be used whenever you type count, so if you want to modify or read the object's variable, you'll need to use self.
Some examples where it makes a difference:
guard let count = calculateCount() as? Int else { return }
self.count = count
init(count: Int) {
self.count = count
}
func updateCount(_ count: Int) {
self.count = count
}
Yes there are some benefits.
Using keywords like self or init or Swift prevent Xcode from ambiguity of overloads
make it compile faster
brings autocomplete suggestions faster;
that's it! Even though you use them explicitly, the compiler removes them from compiled code for compressing reasons. But it is not preferred! It's all about the scope of variables and functions.
Take a look at this example:
let name = "global variable"
class MyClass {
let name = "object variable"
func testScopes() {
let name = "function local variable"
print(name) //prints: function local variable
print(self.name) //prints: object variable
print(MyProject.name) // prints: global variable
}
}
let myObject = MyClass()
myObject.testScopes()
Here are three variables with three different valid scopes. You can refer to each one you need differently.
Swift community suggested:
For conciseness, avoid using self since Swift does not require it to access an object's properties or invoke its methods.
Use self only when required by the compiler (in #escaping closures, or
in initializers to disambiguate properties from arguments). In other
words, if it compiles without self then omit it.
But it's ultimately up to you and your company's code style guide.
Aside from the practical reason where it is required when there is a local variable or parameter with the same name, I do it because for a couple of reasons:
Habit from Objective-C
It explicitly shows me (and anyone else that looks at my code) that I am accessing a property, not a local variable; ie. this action may have consequences (or be influenced by events) outside of the current context.
My personal convention is to only use self in closures. For a few reasons.
It tells me, as a developer, that we are explicitly in a closure, because self is required.
self is very important in closures, and lets us know of possible retain cycles and memory leaks when we capture self strongly.
It is redundant when not in a closure, when there are not multiple variables of the same name inside the same or different scopes.
One thing I will say, when coding, using self. is a quick way to see what's available in the class or struct we are in. However, I will remove it after I find what I need.

ObjectIdentifier needed for Swift equality?

We have multiple instances of a custom Swift class, which inherits from SKSpriteNode, and were able to execute the following code (grossly simplified for this question) correctly:
let instance1 = CustomClass()
let instance2 = CustomClass()
let instance3 = CustomClass()
let instance4 = CustomClass()
let array1 = [instance1, instance2]
let array2 = [instance3, instance4]
func check(testInstance: CustomClass) -> Bool {
return array1.filter({ $0 == testInstance }).count > 0
}
check(testInstance: instance3)
In other words, executing check(testInstance: instance3) returned false as expected.
However, we made a bunch of changes, and check stopped working.
CustomClass does not implement the Equatable protocol. We just want to detect unique instances.
It only started working when we used ObjectIdentifier, meaning the function changed to this:
func check(testInstance: CustomClass) -> Bool {
return array1.filter({ ObjectIdentifier($0) == ObjectIdentifier(testInstance) }).count > 0
}
Why is ObjectIdentifier needed, and when should it be used for object equality?
This was written with Swift 3.
Why is ObjectIdentifier needed, and when should it be used for object equality?
You don't need to use ObjectIdentifier in order to perform an identity comparison in this case, you can simply use the identity operator === instead which, as Martin says here, for class instances is equivalent to using ObjectIdentifier's == overload:
func check(testInstance: CustomClass) -> Bool {
return array1.contains(where: { $0 === testInstance })
}
Also note we're using contains(where:) over filter{...}.count > 0, as the former will short-circuit upon finding a matching element, whereas the latter evaluates the entire sequence (and creates an unnecessary intermediate array).
The direct use of == to perform an identity comparison of objects may have worked due to the fact that CustomClass ultimately inherits from NSObject, which conforms to Equatable by defining an == overload that calls isEqual(_:), which by default performs an identity comparison.
However in general, this should not be relied upon – the implementation of isEqual(_:) can be overridden to perform a comparison based on property values rather than identity. Furthermore, semantically Equatable requires that the implementation of == is based all on visible aspects (i.e property values) of the instances being compared.
From the documentation:
Equality implies substitutability — any two instances that compare
equally can be used interchangeably in any code that depends on their
values. To maintain substitutability, the == operator should take into
account all visible aspects of an Equatable type.
Therefore using == for an identity comparison on your class was never correct, even though it may have worked initially.
As for when ObjectIdentifier should be used, really you should never need it just to perform an identity comparison. For classes, you should use the === operator, and for metatypes, you should simply use the == overload defined specifically for them (as in that case, identity just happens to equality, as each new metatype instance is unique).
The main use of ObjectIdentifier is really its hashValue implementation, which is derived from the pointer value of the thing that it's initialised with. This can be useful, for example, in allowing metatypes to be Dictionary keys (compare Make a Swift dictionary where the key is "Type"?).

Defining Delegate

I am a bit confused about the code below and why the last 2 attempts to define a handler (Delegate) wont work.
//this works
let serializer_setting = new JsonSerializerSettings(Error = fun (sender:obj) (args:Serialization.ErrorEventArgs) -> ())
//this doesnt
let err_handler1 (sender:obj) (args:Serialization.ErrorEventArgs) = ()
let serializer_setting1 = new JsonSerializerSettings(Error = err_handler1)
//neither this
let err_handler2 = fun (sender:obj) (args:Serialization.ErrorEventArgs) -> ()
let serializer_setting2 = new JsonSerializerSettings(Error = err_handler2)
Aren't they exactly the same?
Edit
I also tried this
type Delegate = delegate of obj * ErrorEventArgs -> Unit
let err_handler1 (sender:obj) (args:Serialization.ErrorEventArgs) = ()
let serializer_setting1 = new JsonSerializerSettings(Error = new Delegate(err_handler1))
But this gives me the following error
Error 1 This expression was expected to have type
System.EventHandler<Serialization.ErrorEventArgs>
but here has type
Delegate
Edit 2
Taking the clue from Fyodor below if I do this
let serializer_setting1 = new JsonSerializerSettings(Error = System.EventHandler<Serialization.ErrorEventArgs>(err_handler1))
It works and this also makes sense - However I still don't understand why my approach using a Delegate wont work.
The two latter examples are F# functions, which are actually not normal .NET delegates.
For purposes of interoperability with the rest of .NET, however, the F# compiler will convert an F# function to a compatible delegate type when it can see that this is the expected type.
In the first example, Error must be a delegate, so the F# compiler can infer that it must perform the conversion.
In the two latter examples, the types of the functions are inferred by the compiler without taking into account how they're used, because the F# compiler only interprets code in a single pass from top to bottom.
When the compiler reaches the expression where the function is attempted assigned to Error, the function already has the incorrect type.
See the documentation for more information about delegates in F#.

initializing class properties before use in Swift/iOS

I'm having trouble grasping the proper way of instantiating variables that always need to be set before an object is fully functional but may need to be instantiated after the constructor. Based on Swift's other conventions and restrictions it seems like there is a design pattern I'm unaware of.
Here is my use case:
I have a class that inherits from UIViewController and will programmatically create views based on user actions
I need to attach these views to this class, but to do so I need to retrieve their content based on configuration data supplied by another controller
I don't care if this configuration data is passed to the constructor (in which case it would always be required) or supplied by a secondary call to this object before it is used
My problem seems to be that both of the approaches in bullet 3 seem flawed.
In the first case, there is only one legitimate constructor this class can be called with, yet I'm forced to override other constructors and initialize member variables with fake values even if the other constructors are never intended to be used (I'm also trying to keep these variables as let types based on Swift's best practices).
In the second case, I'm effectively splitting my constructor into two parts and introduce an additional point of failure in case the second part fails to be called prior to class being used. I also can't move this second part to a method that's guaranteed to be called prior to usage (such as viewDidLoad) because I still need to pass in additional arguments from the config. While I can make sure to call the initPartTwo manually, I'd prefer to have a mechanism that better groups it with the actual constructor. I can't be the first one to run into this and it seems like there is a pattern I'm not seeing to make this cleaner.
UPDATE:
I ended up going with a modified version of the pattern matt suggested:
struct Thing {
let item1: String
let item2: String
struct Config {
let item3: String
let item4: String
}
var config:Config! {
willSet {
if self.config != nil {
fatalError("tried to initialize config twice")
}
}
}
init() {
self.item1 = ...
self.item2 = ...
...
}
public func phaseTwoInit(item3: String, item4: String) {
self.item3 = item3
self.item4 = item4
...
}
}
var t = Thing()
...
t.phaseTwoInit(...)
...
// start using t
If an initial instance variable property value can't be supplied at object initialization time, the usual thing is to declare it as an Optional. That way it doesn't need to be initialized by the class's initializers (it has a value - it is nil automatically), plus your code subsequently can distinguished uninitialized (nil) from initialized (not nil).
If the Optional if an implicitly unwrapped Optional, this arrangement need have no particular effect on your code (i.e. it won't have to be peppered with unwrappings).
If your objection is that you are forced to open the door to multiple settings of this instance variable because now it must be declared with var, then close the door with a setter observer:
struct Thing {
var name:String! {
willSet {
if self.name != nil {
fatalError("tried to set name twice")
}
}
}
}
var t = Thing()
t.name = "Matt" // no problem
t.name = "Rumplestiltskin" // crash

Generics type constraint vs inheritance

Is there a difference between these two function declarations?
func doSomething<T: UIViewController>(controller: T) {...}
vs.
func doSomething(controller: UIViewController) {...}
In Type Constraint Syntax section of the Apples Swift programming language book, there's this code sample:
func​ ​someFunction​<​T​: ​SomeClass​, ​U​: ​SomeProtocol​>(​someT​: ​T​, ​someU​: ​U​) {
// function body goes here
}
with this description:
The hypothetical function above has two type parameters. The first type parameter, T, has a type constraint that requires T to be a subclass of SomeClass. ...
So in which cases is it better to use generic function described above?
They are different, but in the way you are using them, they amount to pretty much exactly the same result.
The difference is that when you call the generic version, the compiler sets T statically to be whatever type is passed in as the argument. When calling methods on that argument, this makes almost no difference – either way the calls on its methods will be dynamically dispatched, and you can't touch any parts of T that aren't guaranteed to be available from the constraint.
But suppose you made a change to this method to not just take an argument, but also return one, of the same type:
// T here will take the type of whatever is going in/out of the function
// be that UIViewController or a subtype of it
func doSomethingGenerically<T: UIViewController>(controller: T) -> T {
// some logic that results in a new controller being returned
}
// here the return type is fixed to be UIViewController
func doSomethingViaBaseClass(controller: UIViewController) -> UIViewController {
// some logic that results in a new controller being returned
}
Now, suppose you had a subclass of UIViewController that you were passing in, like so:
let subClass: MyUIViewController = ...
let controller1 = doSomethingGenerically(subClass)
let controller2 = doSomethingViaBaseClass(subClass)
Here, the type of the variable controller1 will be MyUIViewController, because that is what was passed in to the function so that is what T is. But the type of the variable controller2 will be UIViewController because that is the fixed type that doSomethingViaBaseClass returns.
Note, this doesn't mean the object they reference will be different - that depends on what the body of the function implements. It's just the type of the variables referring to it that will change.
There are other subtle differences but this is the main one to know about. In the case of structs, however, there are more differences worth noting. As it happens I wrote an article about them yesterday that might help.

Resources