Is there a way to declare an inline function in Swift? - 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

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")

Swifty method for providing 2 closures for a function

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.

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.

Swift: Why to functions have parameters and return value types?

I'm filling a few gaps in my existing Swift programming language skills before moving onto the more advanced features.
I have checked Apples... "Swift Programming Language" guide and Google search shows lots of information about the rules around using the parameters, but I am looking for the overall Why , not the How...
Question:
Why is there a need to have parameters and return value types for functions in Swift?
(I am not asking about the parameter names etc., but a higher level (general) question on 'Why')
I have made a number of programs using simple C-Style functions in Swift, without a need for parameters or return values which works fine as I know what the functions should be doing for me.
Simple e.g.
func printName() {
print("John")
}
However, there are 'exceptions' like some in-built Swift functions.
E.g....
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return colors.count
}
etc. for table view or collection view usage .
So the only reason I see for using parameters + return values (type) in functions is to ensure only specific type of data is inputted and outputted.
In other words, its a way to avoid unexpected outcomes. So acting almost like a Switch statement, where if I have a specific condition is met -- a specific output will occur... (in functions... "an action").
Am I correct in this understanding, in trying to understand why / where one needs to use parameters & / or return values types with Functions? Or are there other practical reasons? If so can you provide an example?
Many thanks in advance!!!!
If you don't use parameters, you're tied to use what's visible in your scope.
if your function is inside a ViewController, all properties inside that VC, also global scope variables (horrible)
if your function is in global scope, you can only use global scope symbols (horrible, again)
You really do want to pass in things using parameters. This way you can:
auto check types (compiles is doing for you)
check for optionality
check value ranges
test your functions using Unit Tests. if you use global symbols, you're tied to that symbols, can't change them
less maintenance: changes outside your function doesn't affect you
Also, having a clear return type helps other developers and your future-self to understand what's returning from that function: a tuple? An optional array? A number? Also, having defined output types helps you with testing your functions.
Using only global variables & procedures (chunks of code to process those global vars) could work on a small scale. That's the old approach use with languages like FORTRAN, BASIC, COBOL... The moment your project grows, you need to isolate one part of your code from the other. For that:
use functions & a functional approach
use OOP
Let's imagine a sum function
func sum(a: Int, b:Int) -> Int {
return a + b
}
What happen if we remove the parameter types
func sum(a, b) -> Int {
return a + b // what?
}
Of course this is not allowed by the compiler but let's try to imagine.
Now a and b could be anything (like a String and a UIImage). How could we write the code to sum 2 things and get an Int?
Another test, let's remove the return type
func sum(a:Int, b:Int) -> ??? {
return a + b
}
Now let's try to invoke our crazy function
let tot: Int = sum(1, b: 2)
but since sum could return any kind of value how can we put the result into an Int constant?

Would this function be allowed in Swift (if it wouldn't crash the compiler)

I got this function, which is a minimised version of an actual use case:
func f (i:Int) -> <T> (x:T) -> T {
return { x in return x }
}
As you see I would like to compute a generic function based on some input.
But as you can see in Xcode or on swiftstub, this function crashes the compiler.
Does anybody know if Swift is supposed to support such definitions?
This no longer crashes the compiler when I try it on 1.2b3. However, it’s not valid syntax.
If you want to return a function where the type is determined up-front at the time f is called, this would do it:
func f<T>(i:Int) -> T -> T {
return { x in return x }
}
// need to tell the compiler what T actually is...
let g = f(1) as Int->Int
g(2) // returns 2
However, Swift does not support the ability to define “generic” closures, i.e. closures where the type is determined not on creation of the closure, but at the point when that closure is actually called. This would require higher-ranked polymorphism, something that isn’t currently available (though maybe in the future, who knows – would be a very nice feature to have). For now, the placeholders need to be fully determined at the call site.
Keep in mind that the "generic" nature of Swift generics is kind of a misnomer. The genericness is just a template notation; all genericness is compiled away at compile time - that is, all generics used in one part of your code are resolved (specified) by the way they are called in another part of your code.
But for that very reason, you can't return a generic function as a result of a function, because there is no way to resolve the generic at compile time.
So, while crashing the compiler is not nice (and Apple would like to know about it), your code should not compile either, and to that extent the compiler is correct to resist.