Swifty method for providing 2 closures for a function - swift

I have a function with following syntax:
func myfunc<V1,V2>(to: (V1)->V2, from: (V2)->V1)
and as you see, I'm providing 2 closures to this function. These 2 closures are used for converting V1 to V2 and vice versa. Remember that I cannot provide these conversions as extension to V1 or V2. I like to improve function usability and I want to know what is more common and better approach for providing these 2 as a Swift user.
I have though of 3 ways, each with its own pros and cons.
1st approach: Use current syntax.
func myfunc<V1,V2>(to: (V1)->V2, from: (V2)->V1)
Pros: User provides 2 closure, so he can organize code better. In addition, he can provide them in-place.
Cons: Function call will become long and can only use trailing closure for second closure.
2nd approach: Use a single closure for both and distinguish them through a paramether.
enum ConvertClosure {
case .to(Any)
case .from(Any)
}
func myfunc<V1,V2>(operation: (ConvertClosure)->Any)
Pros: Function call becomes simpler and we can use trailing closure too.
Cons: Responsibility of 2 closures are now in a single one, so it becomes more complex. Cannot add generic type checking and need to use Any for enum case argument and return type of function.
3rd approach: Use protocol rather than closure.
protocol ConvertOperation {
associatedtype InVal
associatedtype OutVal
func to(_ val: InVal) -> OutVal
func from(_ val: OutVal) -> InVal
}
func myfunc<V1,V2>(operation: ConvertOperation)
where ConvertOperation.InVal == V1, ConvertOperation.OutVal == V2
Pros: Function call becomes simpler. We have type checking from generics.
Cons: We need to conform to protocol which cannot be done in place. Approach is not using closure, so it may not be very Swifty.
Which method is more suitable for a Swift user? Can you suggest any better method?

This might be a bit opinion based but the general rule is:
Use the most specific type as possible. You want types to catch bugs for you during compilation.
Use protocols when you want to reuse the functionality. A protocol will require you to use a struct/class that will implement it, therefore making it harder to use. Therefore it's better when you already have an object that can conform to that protocol or when the functionality is reused, therefore you can create an object and use it multiple times.
To comment more on your cases:
You should not be using trailing closures if there is more than one closure parameter because that affects readability. However, this is not a bad solution and it's pretty common.
This is generally a bad solution because it uses Any type which breaks rule 1 above. Always minimize usage of Any. Most applications should not use it at all.
This is not a bad solution, however see rule 2. I will be optimal only in specific use cases.
Also consider NSObject is basically the same as Any. In general you should avoid its usage in Swift code because you are basically resigning on type checking.
Also note that you should not aim for code to be as short as possible. Always aim for readability.
We cannot probably give a more specific advise without knowing the exact use case.

Related

Documentation comment for loop variable in Xcode

I know that we can use
/// index variable
var i = 0
as a documentation comment for a single variable.
How can we do the same for a loop variable?
The following does not work:
var array = [0]
/// index variable
for i in array.indices {
// ...
}
or
var array = [0]
for /** index variable */ i in array.indices {
// ...
}
Background:
The reason why I don’t use "good" variable names is that I’m implementing a numerical algorithm which is derived using mathematical notation. It has in this case only single letter variable names. In order to better see the connection between the derivation and the implementation I use the same variable names.
Now I want to comment on the variables in code.
The use of /// is primarily intended for use of documenting the API of of a class, struct, etc. in Swift.
So if used before a class, func, a var/let in a class/struct, etc. you are attaching documentation to that code aspect that Xcode understands how to show inline. It doesn’t know how to pickup that information for things inside of function since at this time that is not the intention of /// (it may work for simple var/let but not likely fully on purpose).
Instead use a simple // code comment for the benefit of any those working in the code however avoid over documenting the code since good code is likely fairly self explaining to anyone versed in the language and adding unneeded documentations can get in the way of just reading the code.
This is a good reference for code documentation in Swift at this time Swift Documentation
I woud strongly push back on something like this if I saw it in a PR. i is a massively well adopted "term of art" for loop indices. Generally, if your variable declaration name needs to be commented, you need a better variable name. There are some exceptions, such as when it stores data with complicated uses/invariants that can't be captured in a better way in a type system.
I think commenting is one area that beginners get wrong, mainly from being misled by teachers or by not yet fully understanding the purpose of comments. Comments don't exist to create an english based, psuedo-programming language in which your entire app will be duplicated. Understanding the programming language is a minimal expectation out of contributors to a project. Absolutely no comments should be explaining programming language features. E.g. var x: Int = 0 // declares a new mutable variable called x, to the Int value 0, with the exception of tutorials for learning Swift.
Commenting in this manner might seem like it's helpful, because you could argue it explains things for beginners. That may be the case, but it's suffocating for all other readers. Imagine if novel had to define all the English words they used.
Instead, the goal of documentation to explain the purpose and the use of things. To answer such questions as:
Why did you implement something this way, and not another way?
What purpose does this method serve?
When will this method of my delegate be called?
Case Study: Equatable
For a good example, take a look at the documentation of Equatable
Some things to notice:
It's written for an audience of Swift developers. It uses many things, which it does not explain such as, arrays, strings, constants, variable declaration, assignment, if statements, method calls (such as Array.contains(_:)), string interpolation, the print function.
It explains the general purpose of this protocol.
It explains how to use this protocol
It explains how you can adopt this protocol for your own use
It documents contractual requirements that cannot be enforced by the type system.
Since equality between instances of Equatable types is an equivalence relation, any of your custom types that conform to Equatable must satisfy three conditions, for any values a, b, and c:
a == a is always true (Reflexivity)
a == b implies b == a (Symmetry)
a == b and b == c implies a == c (Transitivity)
It explains possible misconceptions about the protocol ("Equality is Separate From Identity")

Swift Generics... Checking conformance to protocol with associated type

I'm trying to write a generic function in Swift that takes any number, Int, Float, Double, etc. by setting the generic type to <T: Numeric>. So,
func doSomething<T: Numeric>(with foo: T, and bar: T) -> T {
// body
}
Most of the body will work for any Numeric type, but along the way, I need to find the remainder... which means I need a different approach for FloatingPoint types vs. Integer types.
When T is an Int, this means using the modulo operator:
let remainder = foo % bar
However, when T is a Double or Float, the modulo operator doesn't work and I need to use the truncatingRemainder(dividingBy:) method:
let remainder = foo.truncatingRemainder(dividingBy: bar)
Where I'm struggling is to find a way to sift these out. In theory, I should just be able to do something like this:
var remainder: T
if T.self as FloatingPoint { // <- This doesn't work
remainder = foo.truncatingRemainder(dividingBy: bar)
} else {
remainder = foo % bar
}
This, of course, leads to this error, since FloatingPoint has an associated type:
error: protocol 'FloatingPoint' can only be used as a generic constraint because it has Self or associated type requirements
I understand this error... essentially, FloatingPoint is generic with a still-generic associated type for the adopting type to define.
However, I would like to know the best way to conditionally run select blocks of code that only apply to some more narrowly-defined Protocol than defined with the generic param (T).
Specifically, is there a way to define a single generic function to handle all Numeric types, then differentiate by FloatingPoint vs. Integer types within.
There are a couple issues at foot here.
Numeric is the wrong protocol if you're looking to take remainders.
Unless I am misreading the documentation for Numeric, a matrix type could reasonably conform to Numeric. If a matrix were passed into your function, you would have no real way to compute remainders because that's not a well-defined notion. Consequently, your function shouldn't be defined on all Numeric types. The solution is to define a new protocol which describes types with well-defined remainders. Unfortunately, as Alexander notes in the comments...
Swift will not allow you to extend a protocol to conform to another protocol.
There are various technical reasons for this restriction, mostly centering around difficulties when a type would conform to a protocol in multiple ways.
I think you have two reasonable solutions.
A. Make two different overloads of doSomething, one with T: FloatingPoint and the other with T: BinaryInteger. If there is too much shared code between these implementations, you could refactor the doSomething into multiple functions, most of which would be defined on all of Numeric.
B. Introduce a new protocol RemainderArithmetic: Numeric which describes the operations you want. Then, write explicit conformances for all the particular types you want to use e.g. extension Double: RemainderArithmetic and extension UInt: RemainderArithmetic.
Neither of these solutions are particularly appealing, but I think they have one key advantage: Both of these solutions make clear the particular semantics of the types you are expecting. You are not really anticipating types other than BinaryInteger's or FloatingPoint's, so you shouldn't accept other types. The semantics of remainders can be extremely tricky as evidenced by the wide range of behaviors described on the wikipedia page for mod. Therefore, it probably isn't very natural to be defining a function the same way across integers and floating points. If you are certain that is what you want to do, both of these solutions make your assumptions about what types you are expecting explicit.
If you aren't satisfied by either of these solutions and can provide more details about what exactly you're trying to do, we might be able to find something else.
This doesn't sound like a good use case for a generic. You'll notice that operators like + are not generic in Swift. They use overloading, and so should you.

Is there an objective reason I can't have a single-element tuple with an element label?

In Swift up to and including Swift 3, I can't create a single-element tuple where the element is named. So func foo() -> Bar is fine whereas func foo() -> (bar: Bar) produces a compiler error.
I can, however, think of a few possible uses for this pattern, e.g.
func putTaskOnQueue() -> (receipt: CancellableTask)
func updateMyThing() -> (updatedSuccessfully: Bool)
...where the label is used to reduce ambiguity as to what the return value represents.
Obviously there are various ways I could re-design my apis to work around this limitation, but I'm curious as to why it exists.
Is this a compiler limitation? Would allowing element labels on 1-tuples break parsing of some other piece of grammar? Has this been discussed as part of the Swift Evolution system?
To be clear: I am not soliciting opinions as to the correctness of the examples above. I'm after explanations (if they exist) as to why this is not technically possible.
Yes, it's due to limitations in the compiler. There are no one-tuples in Swift at all. Every T is trivially convertible to and from (T). SE-110 and SE-111 should improve things, but I'm not sure it will be enough to make this possible and I don't believe any of the current proposals explicitly do make it possible.
It has been discussed on swift-evolution. It's not a desired feature of the language; it's a result of other choices.
The Swift Evolution process is very open. I highly recommend bringing questions like this to the list (after searching the archives; admittedly not as simple as you would like it to be). StackOverflow can only give hearsay; the list is much more definitive.

Is there a way to declare an inline function in Swift?

I'm very new to the Swift language.
I wanted to declare an inline function just like in C++
so my func declaration looks like this:
func MyFunction(param: Int) -> Int {
...
}
and I want to do something like this:
inline func MyFunction(param: Int) -> Int {
...
}
I tried to search on the web but I didn't find anything relevant maybe there is no inline keyword but maybe there is another way to inline the function in Swift.
Swift 1.2 will include the #inline attribute, with never and __always as parameters. For more info, see here.
As stated before, you rarely need to declare a function explicitly as #inline(__always) because Swift is fairly smart as to when to inline a function. Not having a function inlined, however, can be necessary in some code.
Swift-5 added the #inlinable attribute, which helps ensuring that library/framework stuff are inlineable for those that link to your library. Make sure you read up about it, as there may be a couple of gotchas that might make it unusable. It's also only for functions/methods declared public, as it's meant for libraries wanting to expose inline stuff.
All credit to the answer, just summarizing the information from the link.
To make a function inline just add #inline(__always) before the function:
#inline(__always) func myFunction() {
}
However, it's worth considering and learning about the different possibilities. There are three possible ways to inline:
sometimes - will make sure to sometimes inline the function. This is the default behavior, you don't have to do anything! Swift compiler might automatically inline functions as an optimization.
always - will make sure to always inline the function. Achieve this behavior by adding #inline(__always) before the function. Use "if your function is rather small and you would prefer your app ran faster."
never - will make sure to never inline the function. This can be achieved by adding #inline(never) before the function. Use "if your function is quite long and you want to avoid increasing your code segment size."
I came across an issue that i needed to use #inlinable and #usableFromInline attributes that were introduced in Swift 4.2 so i would like to share my experience with you.
Let me get straight to the issue though, Our codebase has a Analytics Facade module that links other modules.
App Target -> Analytics Facade module -> Reporting module X.
Analytics Facade module has a function called report(_ rawReport: EventSerializable) that fire the reporting calls, This function uses an instance from the reporting module X to send the reporting calls for that specific reporting module X.
The thing is, calling that report(_ rawReport: EventSerializable) function many times to send the reporting calls once the users launch the app creates unavoidable overhead that caused a lot of crashes for us.
Moreover it's not an easy task to reproduce these crashes if you are setting the Optimisation level to None on the debug mode. In my case i was able only to reproduce it when i set the Optimisation level to Fastest, Smallest or even higher.
The solution was to use #inlinable and #usableFromInline.
Using #inlinable and #usableFromInline export the body of a function as part of a module's interface, making it available to the optimiser when referenced from other modules.
The #usableFromInline attribute marks an internal declaration as being part of the binary interface of a module, allowing it to be used from #inlinable code without exposing it as part of the module's source interface.
Across module boundaries, runtime generics introduce unavoidable overhead, as reified type metadata must be passed between functions, and various indirect access patterns must be used to manipulate values of generic type. For most applications, this overhead is negligible compared to the actual work performed by the code itself.
A client binary built against this framework can call those generics functions and enjoy a possible performance improvement when built with optimisations enabled, due to the elimination of abstraction overhead.
Sample Code:
#inlinable public func allEqual<T>(_ seq: T) -> Bool
where T : Sequence, T.Element : Equatable {
var iter = seq.makeIterator()
guard let first = iter.next() else { return true }
func rec(_ iter: inout T.Iterator) -> Bool {
guard let next = iter.next() else { return true }
return next == first && rec(&iter)
}
return rec(&iter)
}
More Info - Cross-module inlining and specialization

Please provide a practical example of how/why you use the SinkOf and SinkType in Swift (part of standard library)?

These are used heavily in the Swift implementation of ReactiveCocoa and any other functional reactive library I bump into so appear to be of interest from that perspective.
It essentially appears to be a struct wrapping a generic value, but this is obviously too simplistic an interpretation. The types have some comments in the swift standard library but I found them a little too vague and google yields little.
I think it helps to think of sinks as the counterpart of generators.
A generator is basically a function of (Void -> T), where T is the type of the thing you're generating. GeneratorType is a protocol that allows structs and classes, etc to act as generators, by giving that function a name: next() -> T. This is handy, because the generator function takes no arguments, so to produce a useful sequence of values, you need a place to keep track of some state between invocations. Generator<T> is a generic base type that conforms to the GeneratorType protocol, and you can inherit from it to implement your own GeneratorType.
So, back to sinks. A sink is the inverse of a generator, meaning it's a function of (T -> Void). It also has an associated protocol SinkType, which lets structs and classes act as sinks by defining the sink function as put(T). And there's a base implementation SinkOf<T>, which you can use directly without subtyping by passing in an implementation of the put function as a closure. Since the sink function returns Void, it's less likely to need internal state, but if you do, you can inherit from SinkOf or implement SinkType on your own class/struct.
So SinkOf doesn't exactly wrap a generic value so much as it wraps a function that takes a generic value and does something with it. In the forthcoming ReactiveCocoa 3 rewrite, they're used to replace the RAC 2 concept of a "subscriber".
In RAC 2, a signal outputs events by calling the sendNext:, sendError:, and sendCompleted methods of an object that implements the RACSubscriber protocol. RAC 3 replaces the separate methods with a sink of Events, where an Event<T,ErrorType> is an enum that can be one of the cases .Next(T), .Error(ErrorType), and .Completed, plus the new .Interrupted case.
Wrapping up all the event types in a single enumeration makes it clearer what a signal is all about: it's a stream of events. Events arrive one at a time, and can be one of four types (three in RAC2). Without swift's enum type, those events had to be dispatched separately, since the type of value associated with an event is different for each event type. With enums that can carry values of different types, all you need to implement RACSubscriber is a place to put the Event, or in other words, a sink.
That still leaves the question of why to bother having a SinkType instead of just passing around closures of type (T -> Void). The docs only really talk about the compiler optimization benefits, but I personally think it's useful because it gives you a name to work with. If I see a closure of (T -> Void), I have to briefly pause to parse out the types, and if I'm passing them around all the time there's a lot of parens and arrows cluttering up my definitions.
Plus, it's a nice conceptual match if you're working with generators. Since a RAC Signal is conceptually a generator of events, it makes sense to talk in terms of sinks, which are the generator's natural complement.