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

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.

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.

Does Safety in Swift affect Performance?

While learning Swift, I have seen many cases of safe code vs. unsafe code. A perfect example of this is
as? and as!
as?, from my understanding tries to type cast, but if it doesn't cast, returns nil.
as!, from my understanding, tries to type cast, and crashes if it fails.
My question, is why does as!, (and other unsafe syntax with safe counterparts, for that matter) exist? Obviously as? is the better choice. The only answer I could come up with is that maybe using as! is faster for the compiler to compile, and therefore is mainly an optimization piece of syntax.
I'm just curious to know I'm right about safe syntax being a bit slower to compile, since performance matters to me a great deal.
Thank you for your time.
This question is based upon a false premise: The primary choice of as? vs as! is not generally one of performance. Sure, as! potentially might be a bit more efficient, but in an optimized build, the difference is generally negligible.
One chooses as! vs as? based upon the context:
If the cast can possibly fail at runtime, then you'd use as?. Of course you add code to check to see whether the cast succeeded or not.
A common example of a cast that could fail would be whenever the source of the data is some external source (e.g. user input or a network request). A user could paste text values into a field in which you were expecting only numeric values. An external web server could be unavailable or it could even return data in an unexpected format. You'd want to use as? to detect these situations and handle it gracefully.
But if the cast can not possibly fail at runtime, you use as!. But you do so less for performance reasons than for reasons of clarity and writing concise code.
A common example of a cast that cannot fail would be when retrieving a cell prototype from a storyboard, where you know the base type was set in Interface Builder, though the Cocoa API cannot know this. It would be ineffiencient to add a lot of code checking to see if the base type was set correctly (especially since this would be a fatal programming error, anyway) and leads to code with a lot of syntactic noise with no benefit. And if you don't do it correctly, you could easily accidentally suppress an error that you really would want to flush out during the testing process, making it harder to find the problem. This is a good use case for as! syntax.
as! is not unsafe unless your code before it has failed to ensure the cast can't fail. Imagine a situation where your code has already verified the object can indeed be cast to a particular protocol. If for whatever reason you find it convenient to not create a new local variable of that type and cast the first variable to it, then using as! can be appropriate.
The same logic goes for implicitly unwrapped optionals. Since when your view controller is instantiated, an IBOutlet property can't be assigned yet (storyboard hasn't loaded yet), the property has to be optional. But it's irksome to have to use the property as an optional throughout the class when you know the storyboard has loaded. In fact, if there is a problem with locating the storyboard element and assigning it, a 100% guaranteed crash is desired so that the developer can always spot and fix the problem.
So returning to as!, this raises a second case of when it's appropriate to use: whenever a crash is the most desirable outcome of the failed cast.
So it's not about compiler speed. It's about code logic convenience. There are appropriate times to use it, and for those times, it's a more compact and easier to read way of representing your logic goals.
As you say, as! should hardly ever be used. There are a few cases, though, where due to legacy issues, the compiler doesn't know what type something should be, even though the developer does. One example of this is the NSCopying protocol. Because Objective-C was not as strict about type safety as Swift, copy() returns an id, which is bridged to Any in Swift. However, when you use copy(), mutableCopy(), and friends, you usually know exactly what type you will get out of it, so as! is typically used to force a cast to the correct type.
let aString: NSAttributedString = ...
let mutableAString = aString.mutableCopy() as! NSMutableAttributedString
You can investigate this question for yourself by compiling something like
func f(a: Any) -> Int {
(a as! Int) + 5
}
vs.
func f(a: Any) -> Int {
((a as? Int) ?? 3) + 5
}
With the Swift 4 compiler, running swiftc -O -emit-assembly on this Swift code produces extremely similar output, which should square with your understanding of how as! works and how we would implement it if it wasn't part of the language:
func forceCast<T>(_ subject: Any) -> T {
return subject as? T ?? fatalError("Could not cast \(subject) to \(T)")
}
It's worth noting, as SmartCat already alluded to, that as! isn't actually "unsafe" in the sense that the Swift compiler authors define that word; because it, like as?, actually specifically checks the type of subject. There is a unsafe-in-the-swift-sense force cast in swift; it's called, unsurprisingly, unsafeBitCast; and is equivalent to a C/Objective-C cast; it doesn't check types and just assumes you knew what you were doing. Will it be faster than as? Without a doubt.
So, to answer your title's question: yes, safety has a cost in Swift. The flip side of the coin is that if you write code that avoids casts and optionality, Swift can (in theory) optimize your code far more aggressively than languages that make less strong safety guarantees.
To answer your actual question; there's no difference between as? and as! in terms of performance.
Other's have already covered why as! exists; it's so you can tell the compiler "I can't explain why to you, but this will always work; trust me".

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

Can a Swift subscript return a variable?

In C#, the only indexer that actually returns a variable1,2 are array indexers.
void Make42(ref int x) {x=42;}
void SetArray(int[] array){
Make42(ref array[0]);} //works as intended; array[0] becomes 42
void SetList(List<int> list){
Make42(ref list[0]);} //does not work as intended, list[0] stays 0
In the example above, array[0] is a variable, but list[0] is not. This is the culprit behind many developers, writing high-performance libraries, being forced to write their own List implementations (that, unlike the built-in List, expose the underlying array) to get benchmark worthy performance out of the language.
In Swift, ref is called inout and indexer seems to be called subscript. I'm wondering if there's any mechanisms in Swift's subscript to explicitly return a variable rather than a value (a value can be a value-type or reference-type).
If I may bring in C++ parlance, you'd be looking to return a reference to a value. I'm using the term here because it's generally better understood by the programming crowd.
The reason C# limits it to just arrays is that returning arbitrary references may compromise the language's safety guarantees if not done properly.
There appears to be no syntax to return a reference in Swift. Since returning references is hard to verify, and since Swift is rather new and since it aims at being a safe language, it is understandable that Apple didn't go this way.
If you get to a level where you need this kind of performance, you may want to consider C++, in which you can sacrifice almost all the safety you want to get performance.