Why must a protocol operator be implemented as a global function? - ios

I've seen the answer to this Swift Equatable Protocol question that mentions how the == method must be declared in the global scope.
If I don't adopt Equatable, I still could declare == to test for equality between two of my types.
// extension Foo: Equatable {}
func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.bar == rhs.bar
}
struct Foo {
let bar:Int
}
The fact that its implementation needs to be declared at a global scope, makes it seem incidental to and distinct from a protocol, even if Equatable was adopted.
How is the Equatable protocol anything more than syntactic sugar that merely lets (us and) the compiler safely know that our type implemented the required method of the protocol?
Why does the operator implementation have to be globally declared, even for a protocol? Is this due to some different way that an operator is dispatched?

UPDATE
From the Xcode 8 beta 4 release notes:
Operators can be defined within types or extensions thereof. For example:
struct Foo: Equatable {
let value: Int
static func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.value == rhs.value
}
}
Such operators must be declared as static (or, within a class, class final), and have the same
signature as their global counterparts. As part of this change, operator requirements declared in
protocols must also be explicitly declared static:
protocol Equatable {
static func ==(lhs: Self, rhs: Self) -> Bool
}
ORIGINAL
This was discussed on the swift-evolution list recently (2016-01-31 through 2016-02-09 so far). Here's what Chris Lattner said, regarding declaring operators in a struct or class scope:
Yep, this is a generally desirable feature (at least for symmetric operators). This would also be great to get dynamic dispatch of operators within class declarations. I don’t think we have a firm proposal nailing down how name lookup works with this though.
And later (replying to Haravikk):
What are the name lookup issues? Do you mean cases where an operator for Foo == Foo exists in more than one location?
Yes. Name lookup has to have a well defined search order, which
defines shadowing and invalid multiple definition rules.
Personally I’d just stick with what we have now, i.e- treat operator implementations within a specific class/struct as being globally
defined anyway and throw an error if the same signature is declared
more than once.
We need multiple modules to be able to define instances of an
operator, we need operators in extensions, and we need retroactive
conformance to work, as with any other member.

Explanation from the documentation
The operator function is defined as a global function with a function
name that matches the operator to be overloaded.
The function is defined globally, rather than as a method on the
target class or structure, so that it can be used as an infix operator
between existing instances of the target class or structure.
I replaced the name of the concrete structure (Vector2D) in the quotation by a generic expression target class or structure

The fact that its implementation needs to be declared at a global scope, makes it seem incidental to and distinct from a protocol, even if Equatable was adopted.
That is true of every protocol, whether it requires global functions, class methods, or instance methods. You can always implement things independently of whether there is a protocol that is requiring it.
How is the Equatable protocol anything more than syntactic sugar that merely lets (us and) the compiler safely know that our type implemented the required method of the protocol?
That's not sugar. That's the definition of a protocol and the entire point of protocols. It tells you that this type has available these things that can be applied to it.
Why does the operator implementation have to be globally declared, even for a protocol? Is this due to some different way that an operator is dispatched?
Because that's Swift syntax. Operator function implementations have to be global functions. There has been interest from the Swift team to change this to make it more consistent, but today this is just how Swift works.

It was somewhat of a sugar before ie because you needed to manually do the implementation of Equatable. Though Rob Napier brought up a good point that that's what protocols are for.
But that's no longer the case ie just by conformance you get Automated Synthesis and no longer need the boilerplate code.
struct Country: Equatable {
let name: String
let capital: String
var visited: Bool
}
That’s it! The compiler will do the rest.
let france = Country(name: "France", capital: "Paris", visited: true)
let spain = Country(name: "Spain", capital: "Madrid", visited: true)
if france == spain { ... } // false
That being said if you want you can still override the implementation of the == function.
For more see here

In the Swift standard library, the '==' operator is defined. It doesn't have associativity for one side or the other of the comparison and has a numbered precedence in the overall Swift operator order. You can examine this if you CMD-click Swift on 'import Swift'
infix operator == {
associativity none
precedence 130
}
For Int's, the library already has Int/Int8/Int16/Int32/Int64 as Equatable:
public func ==(lhs: Int, rhs: Int) -> Bool
as it does for many other types.
Int is made Hashable in an extension (where to conform to that protocol, you need to create a var hashValue: Int { get } that changes for each execution of the app:
extension Int : Hashable {
public var hashValue: Int { get }
}
The operator '==' and protocols, in general, need to be declared outside struct/enum/class at top-level because you are extending the language and for now, that's how swift is compiled; all Swift's operators are attributes defined at global scope.
For your 'Foo', you adopted Equatable by adding the func:
func ==(lhs: Foo, rhs: Foo) -> Bool {
return lhs.bar == rhs.bar
}
which uses the 'Self' local variables in the protocol:
public protocol Equatable {
public func ==(lhs: Self, rhs: Self) -> Bool
}

Related

Swift variable inheritance in protocol

I have a struct that contains an enum variable (here x) and should conform to a protocol (here A). The enum variable itself is an implementation of a protocol which is also used in the protocol A. But somehow the struct does not conform to the protocol according to the compiler.
Can you help me and explain why this is happening and how it could be solved?
Thanks a lot for the help!
protocol A {
var x: String { get }
}
protocol B {
var x: A { get }
}
enum C: A {
var x: String {
return ""
}
}
struct D: B { // <- Type 'D' does not conform to protocol 'B'
var x: C
}
The new any syntax in Swift 5.7 hopefully will make this a little clearer. The explicit way to write B is:
protocol B {
var x: any A { get }
}
B says that the thing returned from x is an "existential" (any) type. It's a wrapper around A that is of a specific, known size. C is not that. It may have a different size that is not the same as an existential wrapper.
The return type of x must be any A. It cannot just be something that conforms to A. If you want each B-conforming type to have its own version, then you would use an associatedtype:
protocol B {
associatedtype X: A
var x: X { get }
}
With that, D can conform. But there will also be some restrictions put on how you can use B (it becomes a more complicated type), so you should think hard about if this is really your goal. Almost always the correct way to design your protocols is to start with what kind of code will use this protocol, rather than starting with what kind of code will implement this protocol. Starting will the calling code will lead you to what kinds of protocols you really need.
As a side note, your question title suggests you believe that C inherits from A. That's not correct. Structs cannot inherit from anything. A conforms to C. Conforming to a protocol is not the same thing as inheriting from a superclass. In particular, it has situations like this one. Conforming is better thought of as something attached to a type, to allow the type to participate in general-purpose algorithms. It does not fundamentally define what the type is in the way that class inheritance does. Conformance can be attached to a type retroactively, even in another module and without even having access to the type's source code. (I could make String or CBPeripheral conform to B just as easily as D.)

What is #dynamicCallable in Swift?

From Apple's documentation:
The #dynamicCallable attribute lets you call named types like you call
functions using a simple syntactic sugar. The primary use case is
dynamic language interoperability.
Why would you want to use an #dynamicCallable instead of direct approch?
#dynamicCallable is a new feature of Swift 5. From Paul Hudson's article on "How to use #dynamicCallable in Swift" (emphasis mine):
SE-0216 adds a new #dynamicCallable attribute to Swift, which
brings with it the ability to mark a type as being directly callable.
It’s syntactic sugar rather than any sort of compiler magic,
effectively transforming this code:
let result = random(numberOfZeroes: 3)
Into this:
let result = random.dynamicallyCall(withKeywordArguments: ["numberOfZeroes": 3])
[...] #dynamicCallable is the natural extension of
#dynamicMemberLookup [SE-0195], and serves the same purpose: to
make it easier for Swift code to work alongside dynamic languages such
as Python and JavaScript. [...] #dynamicCallable is really flexible about which data
types its methods accept and return, allowing you to benefit from all
of Swift’s type safety while still having some wriggle room for
advanced usage.
Introduce user-defined dynamically "callable" types
Proposal: SE-0216
Authors: Chris Lattner, Dan Zheng
Review Manager: John McCall
Implementation: apple/swift#20305
Decision Notes: Rationale
Status: Implemented (Swift 5)
Introduction
This proposal is a follow-up to SE-0195 - Introduce User-defined "Dynamic Member
Lookup" Types,
which shipped in Swift 4.2. It introduces a new #dynamicCallable attribute, which marks
a type as being "callable" with normal syntax. It is simple syntactic sugar
which allows the user to write:
a = someValue(keyword1: 42, "foo", keyword2: 19)
and have it be rewritten by the compiler as:
a = someValue.dynamicallyCall(withKeywordArguments: [
"keyword1": 42, "": "foo", "keyword2": 19
])
Many other languages have analogous features (e.g. Python "callables", C++ operator(), and
functors in many other languages), but the
primary motivation of this proposal is to allow elegant and natural interoperation with
dynamic languages in Swift.
Swift-evolution threads:
- Pitch: Introduce user-defined dynamically "callable"
types.
- Pitch #2: Introduce user-defined dynamically “callable”
types.
- Current pitch thread: Pitch #3: Introduce user-defined dynamically “callable”
types
Motivation and context
Swift is exceptional at interworking with existing C and Objective-C APIs and
we would like to extend this interoperability to dynamic languages like Python,
JavaScript, Perl, and Ruby. We explored this overall goal in a long design
process wherein the Swift evolution community evaluated multiple different
implementation approaches. The conclusion was that the best approach was to put
most of the complexity into dynamic language specific bindings written as
pure-Swift libraries, but add small hooks in Swift to allow these bindings to
provide a natural experience to their clients.
SE-0195
was the first step in this process, which introduced a binding to naturally
express member lookup rules in dynamic languages.
What does interoperability with Python mean? Let's explain this by looking at
an example. Here's some simple Python code:
class Dog:
def __init__(self, name):
self.name = name
self.tricks = [] # creates a new empty list for each `Dog`
def add_trick(self, trick):
self.tricks.append(trick)
With the SE-0195 #dynamicMemberLookup feature
introduced in Swift 4.2, it is possible to implement a Python interoperability
layer
written in Swift. It interoperates with the Python runtime, and project all
Python values into a single PythonObject type. It allows us to call into the
Dog class like this:
// import DogModule.Dog as Dog
let Dog = Python.import.call(with: "DogModule.Dog")
// dog = Dog("Brianna")
let dog = Dog.call(with: "Brianna")
// dog.add_trick("Roll over")
dog.add_trick.call(with: "Roll over")
// dog2 = Dog("Kaylee").add_trick("snore")
let dog2 = Dog.call(with: "Kaylee").add_trick.call(with: "snore")
This also works with arbitrary other APIs as well. Here is an example working
with the Python pickle API and the builtin Python function open. Note that
we choose to put builtin Python functions like import and open into a
Python namespace to avoid polluting the global namespace, but other designs
are possible:
// import pickle
let pickle = Python.import.call(with: "pickle")
// file = open(filename)
let file = Python.open.call(with: filename)
// blob = file.read()
let blob = file.read.call()
// result = pickle.loads(blob)
let result = pickle.loads.call(with: blob)
This capability works well, but the syntactic burden of having to use
foo.call(with: bar, baz) instead of foo(bar, baz) is significant. Beyond
the syntactic weight, it directly harms code clarity by making code hard to
read and understand, cutting against a core value of Swift.
The proposed #dynamicCallable attribute directly solves this problem.
With it, these examples become more natural and clear, effectively matching the
original Python code in expressiveness:
// import DogModule.Dog as Dog
let Dog = Python.import("DogModule.Dog")
// dog = Dog("Brianna")
let dog = Dog("Brianna")
// dog.add_trick("Roll over")
dog.add_trick("Roll over")
// dog2 = Dog("Kaylee").add_trick("snore")
let dog2 = Dog("Kaylee").add_trick("snore")
Python builtins:
// import pickle
let pickle = Python.import("pickle")
// file = open(filename)
let file = Python.open(filename)
// blob = file.read()
let blob = file.read()
// result = pickle.loads(blob)
let result = pickle.loads(blob)
This proposal merely introduces a syntactic sugar - it does not add any new
semantic model to Swift. We believe that interoperability with scripting
languages is an important and rising need in the Swift community, particularly
as Swift makes inroads into the server development and machine learning
communities. This feature is also precedented in other languages (e.g. Scala's
Dynamic trait), and
can be used for other purposes besides language interoperability (e.g.
implementing dynamic proxy objects).
Proposed solution
We propose introducing a new #dynamicCallable attribute to the Swift language
which may be applied to structs, classes, enums, and protocols. This follows
the precedent of
SE-0195.
Before this proposal, values of these types are not valid in a call expression:
the only existing callable values in Swift are those with function types
(functions, methods, closures, etc) and metatypes (which are initializer
expressions like String(42)). Thus, it is always an error to "call" an
instance of a nominal type (like a struct, for instance).
With this proposal, types with the #dynamicCallable attribute on their
primary type declaration become "callable". They are required to implement at
least one of the following two methods for handling the call behavior:
func dynamicallyCall(withArguments: <#Arguments#>) -> <#R1#>
// `<#Arguments#>` can be any type that conforms to `ExpressibleByArrayLiteral`.
// `<#Arguments#>.ArrayLiteralElement` and the result type `<#R1#>` can be arbitrary.
func dynamicallyCall(withKeywordArguments: <#KeywordArguments#>) -> <#R2#>
// `<#KeywordArguments#>` can be any type that conforms to `ExpressibleByDictionaryLiteral`.
// `<#KeywordArguments#>.Key` must be a type that conforms to `ExpressibleByStringLiteral`.
// `<#KeywordArguments#>.Value` and the result type `<#R2#>` can be arbitrary.
// Note: in these type signatures, bracketed types like <#Arguments#> and <#KeywordArguments#>
// are not actual types, but rather any actual type that meets the specified conditions.
As stated above, <#Arguments#> and <#KeywordArguments#> can be any types
that conform to the
ExpressibleByArrayLiteral
and
ExpressibleByDictionaryLiteral
protocols, respectively. The latter is inclusive of
KeyValuePairs,
which supports duplicate keys, unlike Dictionary.
Thus, using KeyValuePairs is recommended to support duplicate keywords and
positional arguments (because positional arguments are desugared as keyword
arguments with the empty string "" as the key).
If a type implements the withKeywordArguments: method, it may be dynamically
called with both positional and keyword arguments: positional arguments have
the empty string "" as the key. If a type only implements the
withArguments: method but is called with keyword arguments, a compile-time
error is emitted.
Since dynamic calls are syntactic sugar for direct calls to dynamicallyCall
methods, additional behavior of the dynamicallyCall methods is directly
forwarded. For example, if a dynamicallyCall method is marked with throws
or #discardableResult, then the corresponding sugared dynamic call will
forward that behavior.
Ambiguity resolution: most specific match
Since there are two #dynamicCallable methods, there may be multiple ways to
handle some dynamic calls. What happens if a type specifies both the
withArguments: and withKeywordArguments: methods?
We propose that the type checker resolve this ambiguity towards the tightest
match based on syntactic form of the expression. The exact rules are:
If a #dynamicCallable type implements the withArguments: method and it is
called with no keyword arguments, use the withArguments: method.
In all other cases, attempt to use the withKeywordArguments: method.
This includes the case where a #dynamicCallable type implements the
withKeywordArguments: method and it is called with at least one keyword
argument.
This also includes the case where a #dynamicCallable type implements only
the withKeywordArguments: method (not the withArguments: method) and
it is called with no keyword arguments.
If #dynamicCallable type does not implement the withKeywordArguments:
method but the call site has keyword arguments, an error is emitted.
Here are some toy illustrative examples:
#dynamicCallable
struct Callable {
func dynamicallyCall(withArguments args: [Int]) -> Int { return args.count }
}
let c1 = Callable()
c1() // desugars to `c1.dynamicallyCall(withArguments: [])`
c1(1, 2) // desugars to `c1.dynamicallyCall(withArguments: [1, 2])`
c1(a: 1, 2) // error: `Callable` does not define the 'withKeywordArguments:' method
#dynamicCallable
struct KeywordCallable {
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Int {
return args.count
}
}
let c2 = KeywordCallable()
c2() // desugars to `c2.dynamicallyCall(withKeywordArguments: [:])`
c2(1, 2) // desugars to `c2.dynamicallyCall(withKeywordArguments: ["": 1, "": 2])`
c2(a: 1, 2) // desugars to `c2.dynamicallyCall(withKeywordArguments: ["a": 1, "": 2])`
#dynamicCallable
struct BothCallable {
func dynamicallyCall(withArguments args: [Int]) -> Int { return args.count }
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Int {
return args.count
}
}
let c3 = BothCallable()
c3() // desugars to `c3.dynamicallyCall(withArguments: [])`
c3(1, 2) // desugars to `c3.dynamicallyCall(withArguments: [1, 2])`
c3(a: 1, 2) // desugars to `c3.dynamicallyCall(withKeywordArguments: ["a": 1, "": 2])`
This ambiguity resolution rule works out naturally given the behavior of the
Swift type checker, because it only resolves call expressions when the type
of the base expression is known. At that point, it knows whether the base is a
function type, metatype, or a valid #dynamicCallable type, and it knows the
syntactic form of the call.
This proposal does not require massive or invasive changes to the constraint
solver. Please look at the implementation for more details.
Example usage
Here, we sketch some example bindings to show how this could be used in
practice. Note that there are lots of design decisions that are orthogonal to
this proposal (e.g. how to handle exceptions) that we aren't going into here.
This is just to show how this feature provides an underlying facility that
language bindings authors can use to achieve their desired result. These
examples also show #dynamicMemberLookup to illustrate how they work together,
but elides other implementation details.
JavaScript supports callable objects but does not have keyword arguments.
Here is a sample JavaScript binding:
#dynamicCallable #dynamicMemberLookup
struct JSValue {
// JavaScript doesn't have keyword arguments.
#discardableResult
func dynamicallyCall(withArguments: [JSValue]) -> JSValue { ... }
// This is a `#dynamicMemberLookup` requirement.
subscript(dynamicMember member: JSValue) -> JSValue {...}
// ... other stuff ...
}
On the other hand, a common JavaScript pattern is to take a dictionary of
values as a stand-in for argument labels (called like
example({first: 1, second: 2, third: 3}) in JavaScript). A JavaScript bridge
in Swift could choose to implement keyword argument support to allow this to be
called as example(first: 1, second: 2, third: 3) from Swift code (kudos to
Ben Rimmington for this
observation).
Python does support keyword arguments. While a Python binding could implement
only the withKeywordArguments: method, it is be better to implement both the
non-keyword and keyword forms to make the non-keyword case slightly more
efficient (avoid allocating temporary storage) and to make direct calls with
positional arguments nicer (x.dynamicallyCall(withArguments: 1, 2) instead of
x.dynamicallyCall(withKeywordArguments: ["": 1, "": 2])).
Here is a sample Python binding:
#dynamicCallable #dynamicMemberLookup
struct PythonObject {
// Python supports arbitrary mixes of keyword arguments and non-keyword
// arguments.
#discardableResult
func dynamicallyCall(
withKeywordArguments: KeyValuePairs<String, PythonObject>
) -> PythonObject { ... }
// An implementation of a Python binding could choose to implement this
// method as well, avoiding allocation of a temporary array.
#discardableResult
func dynamicallyCall(withArguments: [PythonObject]) -> PythonObject { ... }
// This is a `#dynamicMemberLookup` requirement.
subscript(dynamicMember member: String) -> PythonObject {...}
// ... other stuff ...
}
Limitations
Following the precedent of SE-0195, this attribute must be placed on the
primary definition of a type, not on an extension.
This proposal does not introduce the ability to provide dynamically callable
static/class members. We don't believe this is important given the goal of
supporting dynamic languages like Python, but it could be explored if a use
case is discovered in the future. Such future work should keep in mind that
call syntax on metatypes is already meaningful, and that ambiguity would have
to be resolved somehow (e.g. through the most specific rule).
This proposal supports direct calls of values and methods, but subsets out
support for currying methods in Smalltalk family languages. This is just an
implementation limitation given the current state of currying in the Swift
compiler. Support can be added in the future if there is a specific need.
Source compatibility
This is a strictly additive proposal with no source breaking changes.
Effect on ABI stability
This is a strictly additive proposal with no ABI breaking changes.
Effect on API resilience
This has no impact on API resilience which is not already captured by other
language features.
Future directions
Dynamic member calling (for Smalltalk family languages)
In addition to supporting languages like Python and JavaScript, we would also
like to grow to support Smalltalk derived languages like Ruby and Squeak. These
languages resolve method calls using both the base name as well as the
keyword arguments at the same time. For example, consider this Ruby code:
time = Time.zone.parse(user_time)
The Time.zone reference is a member lookup, but zone.parse(user_time) is a
method call, and needs to be handled differently than a lookup of zone.parse
followed by a direct function call.
This can be handled by adding a new #dynamicMemberCallable attribute, which
acts similarly to #dynamicCallable but enables dynamic member calls (instead
of dynamic calls of self).
#dynamicMemberCallable would have the following requirements:
func dynamicallyCallMethod(named: S1, withArguments: [T5]) -> T6
func dynamicallyCallMethod(named: S2, withKeywordArguments: [S3 : T7]) -> T8
Here is a sample Ruby binding:
#dynamicMemberCallable #dynamicMemberLookup
struct RubyObject {
#discardableResult
func dynamicallyCallMethod(
named: String, withKeywordArguments: KeyValuePairs<String, RubyObject>
) -> RubyObject { ... }
// This is a `#dynamicMemberLookup` requirement.
subscript(dynamicMember member: String) -> RubyObject {...}
// ... other stuff ...
}
General callable behavior
This proposal is mainly directed at dynamic language interoperability. For this
use case, it makes sense for the dynamicallyCall method to take a
variable-sized list of arguments where each argument has the same type.
However, it may be useful to support general callable behavior (akin to
operator() in C++) where the desugared "callable" method can have a fixed
number of arguments and arguments of different types.
For example, consider something like:
struct BinaryFunction<T1, T2, U> {
func call(_ argument1: T1, _ argument1: T2) -> U { ... }
}
It is not unreasonable to look ahead to a day where sugaring such things is
supported, particularly when/if Swift gets variadic
generics.
This could allow typesafe n-ary smart function pointer types.
We feel that the approach outlined in this proposal supports this direction.
When/if a motivating use case for general callable behavior comes up, we can
simply add a new form to represent it and enhance the type checker to prefer
that during ambiguity resolution. If this is a likely direction, then it may be
better to name the attribute #callable instead of #dynamicCallable in
anticipation of that future growth.
We believe that general callable behavior and #dynamicCallable are orthogonal
features and should be evaluated separately.
Alternatives considered
Many alternatives were considered and discussed. Most of them are captured in
the "Alternatives Considered" section of
SE-0195.
Here are a few points raised in the discussion:
It was suggested that we use subscripts to represent the call
implementations instead of a function call, aligning with
#dynamicMemberLookup. We think that functions are a better fit here: the
reason #dynamicMemberLookup uses subscripts is to allow the members to be
l-values, but call results are not l-values.
It was requested that we design and implement the 'static callable' version
of this proposal in conjunction with the dynamic version proposed here. In
the author's opinion, it is important to consider static callable support as
a likely future direction to make sure that the two features sit well next
to each other and have a consistent design (something we believe this
proposal has done) but it doesn't make sense to join the two proposals. So
far, there have been no strong motivating use case presented for the static
callable version, and Swift lacks certain generics features (e.g. variadics)
that would be necessary to make static callables general. We feel that static
callable should stand alone on its own merits.

Swift ExpressibleByIntegerLiteral - How exactly does it work?

Taken from iOs 10 Programming Fundamentals:
"Because Nest adopts ExpressibleByIntegerLiteral, we can pass an Int where a nest is expected, and our init(integerLiteral:) will be called AUTOMATICALLY....."
struct Nest : ExpressibleByIntegerLiteral {
var eggCount : Int = 0
init() {}
init(integerLiteral val: Int) {
self.eggCount = val
}
}
Okay so my question is this...How does it get called automatically though?? My logic runs into a brick wall when I try to figure out why. From what I see, you can say:
var eggie : Nest = 5
but... okay where is the logic in how the number 5 after the equal sign is actually a shorthand for:
var eggie : Nest = Nest(5)
AKA the 'standard' way of initializing a new instance...
Is that just something hidden deep inside the ExpressibleByIntegerLiteral protocol that is handling that transformation?
Thanks
It's compiler magic, so unfortunately you cannot declare such a protocol yourself. :(
It has nothing to do with the internal workings of the ExpressibleByIntegerLiteral. The compiler only sees a variable of type Nest on the left and an integer literal on the right. It thinks,
Oh! The Nest type conforms to ExpressibleByIntegerLiteral! And I see an integer literal. This means that I can change the integer literal to Nest(integerLiteral: 5)!
It's as simple as that. This is also true for other ExpressibleByXXXLiteral protocols.
You cannot declare your own ExpressibleByMyClass protocol because the compiler doesn't know about it.
The ExpressibleBy*Literal protocols are Swift protocols to "hook" into special compiler behaviour. Without the compiler doing the lifting in the back, they wouldn't be able to do anything.

What is the difference between '(String)' and 'String' in a Swift error message

I wrote a function that takes a non-optional String as a parameter.
I declared a variable property of type String, which is also not an optional.
When I try to call my function with this property as an argument, I get the following error.
Cannot invoke 'localesForCountryCode' with an argument list of type '(String)'
Notice that the error lists the type as '(String)' not 'String'. What do the parens signify? I thought they meant that the type was optional, but nothing is declared as an optional anywhere.
My Function (An extension of NSLocale):
func localesForCountryCode(countryCode: String) -> [NSLocale] {
let localeIdentifiers = localeIdentifiersForCountryCode(countryCode)
var locales = [NSLocale]()
for localeIdentifier in localeIdentifiers {
let localeForIdentifier = NSLocale(localeIdentifier: localeIdentifier)
locales.append(localeForIdentifier)
}
return locales
}
Code That Calls My Function
let currentCountryCode = "US"
var localesForCurrentCountry = [NSLocale]()
func updateWithNewLocation(newLocation: CLLocation) {
geoCoder.reverseGeocodeLocation(newLocation, completionHandler: { (placemarks, error) -> Void in
if placemarks.count > 0 {
let placemark = placemarks.first as! CLPlacemark
self.currentCountry = placemark.country
self.localesForCurrentCountry = NSLocale.localesForCountryCode(self.currentCountryCode)
}
})
}
Update 1
When I move my function code from the NSLocale extension to the view controller from which I am calling the function, the error goes away. Any ideas why this may be the case? Absolutely no changes to the function were made.
Update 2
I continue to run into this problem. The following is another example. Again, it seems to happen only when a function is called as a class method.
I was rereading your question and realized that your question is not really your question. Your problem has nothing to do with parentheses (see below about why). You're just calling the wrong method. NSDateComponentsFormatter is a class. stringFromTimeInterval() is an instance method. You have to crate an actual date formatter to work with. If you want a default one, you can do this:
return NSDateComponentsFormatter().stringFromTimeInterval(unwrappedTimespan)
Note the extra set of parentheses. Your probably don't want the default one, though. You probably want to configure one. See Date Formatters for an introduction to that topic. Note that date formatters can be pretty expensive to create, so you usually want to reuse them.
You're doing the same thing with localesForCountryCode. This is an instance method, not a class method. You have to create an NSLocale first.
This does open up an interesting topic, though. Why does NSDateComponentsFormatter.stringFromTimeInterval() act like a function that you're just passing the wrong arguments to? Why doesn't it say "hey, you're calling a class method?" It's because it is a function that you're just passing the wrong arguments to.
Every method is really just a curried function that takes the target object as the first parameter. See Ole Begemann's quick intro to the topic: Instance Methods are Curried Functions in Swift.
Some more on your explicit question about parentheses:
As others have noted, a (String) is a one-tuple of String. The important point is that in Swift, any type is trivially convertible to a one-tuple of that type, so the extra parentheses here are unimportant. There is no meaningful distinction between String and (String) in Swift.
All Swift functions technically take one value and return one value. So one can correctly think of:
func f(x: Int, y: Int) -> Int
as a function that takes a tuple (Int,y:Int) and returns an Int (or possibly (Int); I believe Swift actually does the former, though). This is subtly connected to how currying works in Swift. In a simpler case:
func f(x: Int)
This is a function that technically takes (Int) and returns (). That's why sometimes you will see (Type) show up in error messages. But it is not a meaningful distinction.
String - it's simple String type.
But (String) - it's a compound type called Tuple.
That means you passing to you function Tuple, not String.
A compound type is a type without a name, defined in the Swift language itself. There are two compound types: function types and tuple types. A compound type may contain named types and other compound types. For instance, the tuple type (Int, (Int, Int)) contains two elements: The first is the named type Int, and the second is another compound type (Int, Int).
In general the error message says (String) because that is the tuple / list of parameters. If you method would expect a String and afterwards an Int an error message might mention (String, paramName: Int)
So basically so far everything looks fine. You need to show us the code for us to be able to fix your exact problem. Because String and (String) normally should match in the given scenario.
Consider the following example:
func k (a:String, b:Int) {}
k(12, b:"123")
which will cause the error
Cannot invoke 'k' with an argument list of type (Int, b:String)
While
k("12", b:123)
does what you would expect.

Does Swift support reflection?

Does Swift support reflection? e.g. is there something like valueForKeyPath: and setValue:forKeyPath: for Swift objects?
Actually does it even have a dynamic type system, something like obj.class in Objective-C?
Looks like there's the start of some reflection support:
class Fruit {
var name="Apple"
}
reflect(Fruit()).count // 1
reflect(Fruit())[0].0 // "name"
reflect(Fruit())[0].1.summary // "Apple"
From mchambers gist, here:
https://gist.github.com/mchambers/fb9da554898dae3e54f2
If a class extends NSObject, then all of Objective-C's introspection and dynamism works. This includes:
The ability to ask a class about its methods and properties, and to invoke methods or set properties.
The ability to exchange method implementations. (add functionality to all instances).
The ability to generate and assign a new sub-class on the fly. (add functionality to a given instance)
One shortcoming of this functionality is support for Swift optional value types. For example Int properties can be enumerated and modified but Int? properties cannot. Optional types can be enumerated partially using reflect/MirrorType, but still not modified.
If a class does not extend NSObject, then only the new, very limited (and in progress?) reflection works (see reflect/MirrorType), which adds limited ability to ask a instance about its class and properties, but none of the additional features above.
When not extending NSObject, or using the '#objc' directive, Swift defaults to static- and vtable-based dispatch. This is faster, however, in the absence of a virtual machine does not allow runtime method interception. This interception is a fundamental part of Cocoa and is required for the following types of features:
Cocoa's elegant property observers. (Property observers are baked right in to the Swift language).
Non-invasively applying cross-cutting concerns like logging, transaction management (i.e Aspect Oriented Programming).
Proxies, message forwarding, etc.
Therefore its recommended that clases in Cocoa/CocoaTouch applications implemented with Swift:
Extend from NSObject. The new class dialog in Xcode steers in this direction.
Where the overhead of of a dynamic dispatch leads to performance issues, then static dispatch can be used - in tight loops with calls to methods with very small bodies, for example.
Summary:
Swift can behave like C++, with fast static/vtable dispatch and limited reflection. This makes it suitable for lower level or performance intensive applications, but without the complexity, learning curve or risk of error associated with C++
While Swift is a compiled language, the messaging style of method invocation adds the introspection and dynamism found in modern languages like Ruby and Python, just like Objective-C, but without Objective-C's legacy syntax.
Reference data: Execution overhead for method invocations:
static : < 1.1ns
vtable : ~ 1.1ns
dynamic : ~4.9ns
(actual performance depends on hardware, but the ratios will remain similar).
Also, the dynamic attribute allows us to explicitly instruct Swift that a method should use dynamic dispatch, and will therefore support interception.
public dynamic func foobar() -> AnyObject {
}
The documentation speaks about a dynamic type system, mainly about
Type and dynamicType
See Metatype Type (in Language Reference)
Example:
var clazz = TestObject.self
var instance: TestObject = clazz()
var type = instance.dynamicType
println("Type: \(type)") //Unfortunately this prints only "Type: Metatype"
Now assuming TestObject extends NSObject
var clazz: NSObject.Type = TestObject.self
var instance : NSObject = clazz()
if let testObject = instance as? TestObject {
println("yes!") //prints "yes!"
}
Currently, there is no reflection implemented.
EDIT: I was apparently wrong, see stevex's answer. There is some simple readonly reflection for properties build in, probably to allow IDEs to inspect object contents.
No reflect keyword in Swift 5, now you can use
struct Person {
var name="name"
var age = 15
}
var me = Person()
var mirror = Mirror(reflecting: me)
for case let (label?, value) in mirror.children {
print (label, value)
}
It seems that a Swift reflection API is not a high priority for Apple at the moment. But besides #stevex answer there is another function in the standard library that helps.
As of beta 6 _stdlib_getTypeName gets the mangled type name of a variable. Paste this into an empty playground:
import Foundation
class PureSwiftClass {
}
var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"
println( "TypeName0 = \(_stdlib_getTypeName(myvar0))")
println( "TypeName1 = \(_stdlib_getTypeName(myvar1))")
println( "TypeName2 = \(_stdlib_getTypeName(myvar2))")
println( "TypeName3 = \(_stdlib_getTypeName(myvar3))")
The output is:
TypeName0 = NSString
TypeName1 = _TtC13__lldb_expr_014PureSwiftClass
TypeName2 = _TtSi
TypeName3 = _TtSS
Ewan Swick's blog entry helps to decipher these strings:
e.g. _TtSi stands for Swift's internal Int type.
Mike Ash has a great blog entry covering the same topic.
You might want to consider using toString() instead. It is public and works just the same as _stdlib_getTypeName() with the difference that it also works on AnyClass, e.g. in a Playground enter
class MyClass {}
toString(MyClass.self) // evaluates to "__lldb_expr_49.MyClass"

Resources