Re: [swift-evolution] Swift-Native Alternative to KVO

2016-01-01 Thread Charles Srstka via swift-evolution
> On Jan 1, 2016, at 7:00 PM, Jared Sinclair via swift-evolution 
>  wrote:
> 
> The one-to-many observer pattern could really use a first-party, native Swift 
> solution. The day-to-day practice of writing iOS / OS X applications needs 
> it, and we end up falling back on antiquated APIs like KVO or 
> NSNotificationCenter, or short-lived third-party libraries. This is an 
> essential need that deserves a fresh approach.
> 
> What follows is a rough proposal for a Swift-native “KVO alternative”. 
> 
> 
> What Usage Would Look Like:
> 
> let tweet = Tweet(text: “Hi.”)
> tweet.observables.isLiked.addObserver { (oldValue, newValue) -> Void in
> // this is otherwise just a standard closure, with identical
> // memory management rules and variable scope semantics.
> print(“Value changed.”)
> }
> tweet.isLiked = true // Console would log “Value changed.”
> 
> Behind the Scenes:
> 
> - When compiling a Swift class “Foo", the compiler would also generate a 
> companion “Foo_SwiftObservables” class.
> 
> - When initializing an instance of a Swift class, an instance of the 
> companion “ Foo_SwiftObservables” class would be initialized and set as the 
> value of a reserved member name like “observables”. This member would be 
> implicit, like `self`.
> 
> - The auto-generated “ Foo_SwiftObservables” class would have a corresponding 
> property for every observable property of the target class, with an identical 
> name.
> 
> - Each property of the auto-generated “ Foo_SwiftObservables” class would be 
> an instance of a generic `Observable` class, where `T` would be assigned 
> to the value of the associated property of the target class.
> 
> - The `Observable` class would have two public functions: addObserver() 
> and removeObserver(). 
> 
> - The addObserver() function would take a single closure argument. This 
> closure would have a signature like: (oldValue: T?, newValue: T?) -> Void. 
> 
> - Observer closures would have the same memory management and variable scope 
> rules as any other closure. Callers would not be obligated to remove their 
> observer closures. Doing so would be a non-mandatory best practice.
> 
> 
> Rough Code Examples
> 
> Consider a class for a Twitter client like:
> 
> class Tweet {
> var isLiked: Bool = false
> let text: String
>  
> init(text: String) {
> self.text = text
> }
> }
> The compiler would generate a companion observables class:
> 
> class Tweet_SwiftObservables {
> let isLiked = Observable()
> }
> Notice that only the `isLiked` property is carried over, since the `text` 
> property of `Tweet` is a let, not a var.
> 
> The generic Observable class would be something like (pseudo-codish):
> 
> class Observable {
> typealias Observer = (oldValue: T?, newValue: T?) -> Void
> private var observers = [UInt: Observer]()
>  
> func addObserver(observer: Observer) -> Uint {
> let token: Uint = 0 // generate some unique token
> self.observers[token] = observer
> return token
> }
>  
> func removeObserverForToken(token: Uint) {
> self.observers[token] = nil
> }
> }
> 
> Benefits of This Approach
> 
> It’s familiar. It resembles the core mechanic of KVO without the hassle. It 
> uses existing memory management rules. Everything you already understand 
> about closures applies here.
> 
> It’s type-safe. The Observable generic class ensures at compile-time that 
> your observers don’t receive an incorrect type.
> 
> It’s readable. The syntax is brief without being unclear. Implementing the 
> observation closure at the same call site as addObserver() keeps cause and 
> effect as close together as possible.
> 
> It’s easy. It abandons a stringly-typed API in favor of a compile-time API. 
> Since the Foo_SwiftObservables classes would be auto-generated by the 
> compiler, there’s no need for busywork tasks like keeping redundant manual 
> protocols or keyword constants up to date with the target classes.
> 
> 
> Thanks for reading,
> 
> 
> -- 
> Jared Sinclair
> @jaredsinclair
> jaredsinclair.com  
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
I’ve been thinking about this for a while, as well. I think the problem would 
be better served by a simpler approach. Generating entire new classes is the 
way the existing KVO mechanism works, but I don’t really see the necessity in 
it.

Here’s my counter-pitch: add an “observable" keyword on property declarations, 
so your “isLIked” property would look like this:

class Tweet {
observable var isLiked: Bool = false
let text: String

init(text: String) {
self.text = text
}
}

My first instinct is to make observations based 

Re: [swift-evolution] Better syntax for deferred?

2016-01-02 Thread Charles Srstka via swift-evolution
> On Jan 2, 2016, at 8:37 AM, Tino Heth via swift-evolution 
>  wrote:
> 
>> 
>> Unless I missed something obvious, wouldn't placing "code that always has to 
>> run at the end" actually *at the end* not make more sense? Like this…
> In most cases, you use defer for cleanup tasks - so it make more sense to 
> keep it at the source of the "problem":
> 
> file.open(); defer { file.close() }
> …
> 
> Tino

This. It’s way easier to remember to do necessary cleanup tasks if you add the 
cleanup call right after the call that requires the cleanup. It’s also much 
easier to catch cases where someone has forgotten to do so. Separating the init 
and cleanup by large distances as in the old try/catch/finally mechanism makes 
it easier for things to get out of sync as the code evolves.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Mini-proposal] Require @nonobjc on members of @objc protocol extensions

2016-01-05 Thread Charles Srstka via swift-evolution
> On Jan 4, 2016, at 10:32 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> There is no direct way to implement Objective-C entry points for protocol 
> extensions. One would effectively have to install a category on every 
> Objective-C root class [*] with the default implementation or somehow 
> intercept all of the operations that might involve that selector. 

I can almost do it right now, just hacking with the Objective-C runtime 
functions, so I’d think that if you were actually working with the compiler 
sources, it should be doable. The trouble is on the Swift side; currently there 
aren’t any reflection features that I can find that work on Swift protocols.

If I have a protocol and class, like so:

import Foundation

@objc protocol HasSwiftExtension {}

@objc protocol P: HasSwiftExtension {
optional func foo()
}

extension P {
func foo() { print("foo") }
}

class C: NSObject, P {}

(the optional is there because without it, adding the method in an extension 
causes the compiler to crash on my machine)

And then I have this in Objective-C:

@implementation NSObject (Swizzle)
+ (void)load {
CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

unsigned int classCount = 0;
Class *classes = objc_copyClassList();

Protocol *proto = @protocol(HasSwiftExtension);

for (unsigned int i = 0; i < classCount; i++) {
Class eachClass = classes[i];

if (class_conformsToProtocol(eachClass, proto)) {
unsigned int protoCount = 0;
Protocol * __unsafe_unretained *protocols = 
class_copyProtocolList(eachClass, );

for (unsigned int j = 0; j < protoCount; j++) {
Protocol *eachProto = protocols[j];

if (protocol_conformsToProtocol(eachProto, proto)) {
unsigned int methodCount = 0;
// what we would want would be to pass YES for 
isRequiredMethod; unfortunately,
// adding optional methods to an @objc protocol in an 
extension currently just
// crashes the compiler when I try it. So pass NO, for the 
demonstration.
struct objc_method_description *methods = 
protocol_copyMethodDescriptionList(eachProto, NO, YES, );

for (unsigned int k = 0; k < methodCount; k++) {
struct objc_method_description method = methods[k];

if (!class_respondsToSelector(eachClass, method.name)) {
[SwizzleWrapper swizzleClass:[eachClass class] 
protocol:eachProto method:method];
}
}

free(methods);
}
}

free(protocols);
}
}

free(classes);

NSLog(@"took %f seconds", CFAbsoluteTimeGetCurrent() - startTime);
}
@end

The swizzleClass:protocol:method: method will get called for each missing 
method, assuming I’ve marked the protocols having an extension by making them 
conform to my HasSwiftExtension protocol, which the compiler could add 
automatically. (For the record, the time taken was 0.001501 seconds in my 
testing, while linking against both Foundation and AppKit).

Unfortunately there’s currently no way to go any further, since AFAIK there’s 
no way to reflect on a protocol to get a mapping from selector name to method. 
For this to work, you’d have to store the method names for methods added by 
extensions to @objc protocols as strings somewhere, and then have a reflection 
API to access them. However, if you added that, you could just:

class SwizzleWrapper: NSObject {
class func swizzleClass(aClass: AnyClass, `protocol` aProto: Protocol, 
method: objc_method_description) {
let imp: IMP

// now, just add some reflection for protocols to the language so we can
// figure out what method to call and set imp accordingly, and:

class_addMethod(aClass, method.name, imp, method.types) // ta da!
}
}

The other obvious disclaimer, of course, is that +load is probably not the 
right place to do this; you’d need to set things up such that they would run 
sometime after the Swift runtime has had a chance to finish initializing; the 
code as above probably isn’t safe if the Swift method being called actually 
does anything. But with access to the compiler source, you could make sure to 
get the SetUpStuff() method to run at the appropriate time, so that it could 
call into Swift and do its setup.

(For the record, I’m not advocating actually using the swizzling method 
described above; just pointing out that intercepting the selector is possible. 
Working with the compiler sources, I’d expect more elegant solutions would be 
possible.)

Charles

___
swift-evolution 

Re: [swift-evolution] [Rejected] SE-0009 Require self for accessing instance members

2016-01-06 Thread Charles Srstka via swift-evolution
> On Jan 6, 2016, at 8:56 AM, Greg Parker via swift-evolution 
>  wrote:
> 
>> On Jan 6, 2016, at 6:17 AM, Honza Dvorsky via swift-evolution 
>> > wrote:
>> 
>> I remember this being discussed in the conversation about this proposal and 
>> I haven't seen anyone being *against* there being a compiler flag, assuming 
>> it's off by default.
> 
> We don't want language-changing compiler flags. swiftc doesn't even have 
> flags to control warnings today, though I don't know if we'll be able to 
> preserve that forever.
> 
> Style rules should be enforced by tools other than the compiler. 

I just spent a half hour last night debugging an issue that turned out to be 
caused by something getting written to a property which I thought was being 
written to a local variable, due to implicit self.

Clang had compiler flags to enforce specific stylistic rules, such as 
-Wobjc-missing-property-synthesis for those who disliked the auto-synthesis 
feature (and I never even understood that particular objection). It seems to me 
that this compiler warning would be at least as acceptable as that.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Mini-proposal] Require @nonobjc on members of @objc protocol extensions

2016-01-05 Thread Charles Srstka via swift-evolution
> On Jan 5, 2016, at 9:06 PM, Félix Cloutier  wrote:
> 
> The linker is smart enough to get rid of frameworks that you don't actually 
> use.
> 
> Félix


objc_copyClassList leaves a value of 14694 in classCount. When I just link 
against Foundation it only gives 1581.

otool says:

$ otool -L test
test:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 
120.1.0)
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation 
(compatibility version 300.0.0, current version 1256.1.0)
/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork 
(compatibility version 1.0.0, current version 760.2.5)
/System/Library/Frameworks/Metal.framework/Versions/A/Metal 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Contacts.framework/Versions/A/Contacts 
(compatibility version 0.0.0, current version 0.0.0)
/System/Library/Frameworks/GSS.framework/Versions/A/GSS (compatibility 
version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/CoreMIDIServer.framework/Versions/A/CoreMIDIServer 
(compatibility version 1.0.0, current version 73.0.0)
/System/Library/Frameworks/Python.framework/Versions/2.7/Python 
(compatibility version 2.7.0, current version 2.7.10)

/System/Library/Frameworks/CoreLocation.framework/Versions/A/CoreLocation 
(compatibility version 1.0.0, current version 1615.38.0)
/System/Library/Frameworks/GLKit.framework/Versions/A/GLKit 
(compatibility version 1.0.0, current version 20.0.0)
/System/Library/Frameworks/MapKit.framework/Versions/A/MapKit 
(compatibility version 1.0.0, current version 0.0.0)

/System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
 (compatibility version 1.0.0, current version 756.20.4)

/System/Library/Frameworks/CoreTelephony.framework/Versions/A/CoreTelephony 
(compatibility version 1.0.0, current version 0.0.0)
/System/Library/Frameworks/CloudKit.framework/Versions/A/CloudKit 
(compatibility version 1.0.0, current version 481.8.0)
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/CoreText.framework/Versions/A/CoreText 
(compatibility version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/Collaboration.framework/Versions/A/Collaboration 
(compatibility version 1.0.0, current version 75.0.0)
/System/Library/Frameworks/LDAP.framework/Versions/A/LDAP 
(compatibility version 1.0.0, current version 2.4.0)
/System/Library/Frameworks/AddressBook.framework/Versions/A/AddressBook 
(compatibility version 1.0.0, current version 1679.3.0)
/System/Library/Frameworks/QuickLook.framework/Versions/A/QuickLook 
(compatibility version 1.0.0, current version 0.0.0)

/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl 
(compatibility version 8.5.0, current version 8.5.9)

/System/Library/Frameworks/DiscRecording.framework/Versions/A/DiscRecording 
(compatibility version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/InputMethodKit.framework/Versions/A/InputMethodKit 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/OpenCL.framework/Versions/A/OpenCL 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Photos.framework/Versions/A/Photos 
(compatibility version 1.0.0, current version 350.22.0)
/System/Library/Frameworks/OSAKit.framework/Versions/A/OSAKit 
(compatibility version 1.0.0, current version 104.0.0)

/System/Library/Frameworks/MediaAccessibility.framework/Versions/A/MediaAccessibility
 (compatibility version 1.0.0, current version 62.0.0)
/System/Library/Frameworks/ContactsUI.framework/Versions/A/ContactsUI 
(compatibility version 1.0.0, current version 1679.3.0)

/System/Library/Frameworks/DirectoryService.framework/Versions/A/DirectoryService
 (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility 
version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/StoreKit.framework/Versions/A/StoreKit 
(compatibility version 1.0.0, current version 379.0.0)

/System/Library/Frameworks/OpenDirectory.framework/Versions/A/OpenDirectory 
(compatibility version 1.0.0, current version 1.0.0)

/System/Library/Frameworks/PreferencePanes.framework/Versions/A/PreferencePanes 
(compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/GameplayKit.framework/Versions/A/GameplayKit 
(compatibility version 1.0.0, current version 1.0.0)


Re: [swift-evolution] [Mini-proposal] Require @nonobjc on members of @objc protocol extensions

2016-01-05 Thread Charles Srstka via swift-evolution
> On Jan 5, 2016, at 8:29 PM, Greg Parker <gpar...@apple.com> wrote:
> 
>> 
>> On Jan 5, 2016, at 3:37 PM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Jan 5, 2016, at 11:52 AM, Douglas Gregor <dgre...@apple.com 
>>> <mailto:dgre...@apple.com>> wrote:
>>> 
>>> There are better mechanisms for this than +load. But one would have to deal 
>>> with the dylib loading issue and the need to enumerate root classes to get 
>>> to a complete implementation. Frankly, I don’t think this level of 
>>> Objective-C runtime hackery is worth the effort, hence my suggestion to 
>>> make the existing behavior explicit.
>> 
>> Yeah, +load was just to throw together a quick-and-dirty demonstration, and 
>> not what you’d actually use. You have a point about libraries and bundles; 
>> you’d have to hook into that and rescan each time new code was dynamically 
>> loaded. However, the enumeration of classes only seems to take around 0.001 
>> seconds, so I don’t think it’s terrible.
> 
> Enumeration of classes is terrible: it forces the runtime to perform lots of 
> work that it tries very hard to perform lazily otherwise. I would expect your 
> measured cost to be much higher if you had linked to more high-level 
> libraries (UIKit, MapKit, etc).

That was my gut reaction to the idea also, when I had it, but it seems to run 
pretty fast no matter what I do. I just tried dragging every framework from 
/System/Library/Frameworks into the project, removing only the Java frameworks, 
Kernel.framework, Message.framework, and vecLib.framework. Time taken was 
0.004260 seconds.

It is, of course, ugly and hacky as hell, and that might make a pretty good 
reason not to do it. :-/ What do you think about the other idea, of adding to 
NSObject’s default implementation of +resolveInstanceMethod:? That *would* be 
done lazily, and would avoid all the problems involving dynamically loaded code.

Charles___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal Draft] automatic protocol forwarding

2015-12-29 Thread Charles Srstka via swift-evolution
Strong +1 on this proposal. I use Objective-C’s forwarding mechanisms quite 
often in my custom view code, in order to separate the code managing the outer 
view, the layout of subviews within the view, and business logic into separate 
classes, all while presenting a single, monolithic interface to the user. The 
loss of this ability without writing tons of boilerplate is one of the things 
about Swift that makes me sad.

The one thing I’d change is upgrading the partial forwarding synthesis to the 
original proposal, as that’s a rather important feature IMO.

Charles

> On Dec 29, 2015, at 10:37 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> I have completed a first draft of a proposal to introduce automatic protocol 
> forwarding.  I’m looking forward to feedback from everyone!
> Automatic protocol forwarding
> 
> Proposal: SE- 
> 
> Author(s): Matthew Johnson 
> Status: Review
> Review manager: TBD
> Introduction
> 
> Automatic protocol forwarding introduces the ability to use delegation 
> without the need write forwarding member implementations manually. 
> 
> A preliminary mailing list thread on this topic had the subject protocol 
> based invocation forwarding 
> 
> Motivation
> 
> Delegation is a robust, composition oriented design technique that keeps 
> interface and implementation inheritance separate. The primary drawback to 
> this technique is that it requires a lot of manual boilerplate to forward 
> implemenation to the implementing member. This proposal eliminates the need 
> to write such boilerplate manually, thus making delegation-based designs much 
> more convenient and attractive.
> 
> This proposal may also serve as the foundation for a future enhancement 
> allowing a very concise “newtype” declaration.
> 
> Proposed solution
> 
> I propose introducing a forward declaration be allowed within a type 
> declaration or type extension. The forward declaration will cause the 
> compiler to synthesize implementations of the members required by the 
> forwarded protocols. The synthesized implementations will simply forward the 
> method call to the specified member.
> 
> The basic declaration looks like this:
> 
> forward Protocol, OtherProtocol to memberIdentifier
> The first clause contains a list of protocols to forward. 
> 
> The second clause specifies the identifier of the property to which the 
> protocol members will be forwarded. Any visible property that implements the 
> members required by the protocol is eligible for forwarding. It does not 
> matter whether it is stored, computed, lazy, etc.
> 
> It is also possible to include an access control declaration modifier to 
> specify the visibility of the synthesized members.
> 
> Self parameters
> 
> When a protocol member includes a Self parameter forwarding implementations 
> must accept the forwarding type but supply an argument of the forwardee type 
> when making the forwarding call. The most straightforward way to do this is 
> to simply use the same property getter that is used when forwarding. This is 
> the proposed solution.
> 
> Self return types
> 
> When a protocol member includes a Self return type forwarding implementations 
> must return the forwarding type. However, the forwardee implmentation will 
> return a value of the forwardee type. This result must be used to produce a 
> value of the forwarding type in some way.
> 
> The solution in this proposal is based on an ad-hoc overloading convention. A 
> protocol-based solution would probably be desirable if it were possible, 
> however it is not. This proposal supports forwarding to more than one member, 
> possibly with different types. A protocol-based solution would require the 
> forwarding type to conform to the “Self return value conversion” protocol 
> once for each forwardee type.
> 
> Static members
> 
> When a forwardee value is returned from a static member an initializer will 
> be used to produce a final return value. The initializer must be visible at 
> the source location of the forward declaration and must look like this:
> 
> struct Forwarder {
> let forwardee: Forwardee
> forward P to forwardee
> init(_ forwardeeReturnValue: Forwardee) { //... }
> }
> Instance members
> 
> When a forwardee value is returned from an instance member an instance method 
> will be used to transform the return value into a value of the correct type. 
> An instance method is necessary in order to allow the forwarding type to 
> access the state of the instance upon which the method was called when 
> performing the transformation.
> 
> If the instance method is not implemented the initializer used for static 
> members will be used instead.
> 
> The transformation has the form:
> 
> struct Forwarder 

Re: [swift-evolution] [Mini-proposal] Require @nonobjc on members of @objc protocol extensions

2016-01-06 Thread Charles Srstka via swift-evolution
> On Jan 5, 2016, at 8:55 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> On Jan 5, 2016, at 8:29 PM, Greg Parker <gpar...@apple.com 
>> <mailto:gpar...@apple.com>> wrote:
>> 
>>> 
>>> On Jan 5, 2016, at 3:37 PM, Charles Srstka via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Jan 5, 2016, at 11:52 AM, Douglas Gregor <dgre...@apple.com 
>>>> <mailto:dgre...@apple.com>> wrote:
>>>> 
>>>> There are better mechanisms for this than +load. But one would have to 
>>>> deal with the dylib loading issue and the need to enumerate root classes 
>>>> to get to a complete implementation. Frankly, I don’t think this level of 
>>>> Objective-C runtime hackery is worth the effort, hence my suggestion to 
>>>> make the existing behavior explicit.
>>> 
>>> Yeah, +load was just to throw together a quick-and-dirty demonstration, and 
>>> not what you’d actually use. You have a point about libraries and bundles; 
>>> you’d have to hook into that and rescan each time new code was dynamically 
>>> loaded. However, the enumeration of classes only seems to take around 0.001 
>>> seconds, so I don’t think it’s terrible.
>> 
>> Enumeration of classes is terrible: it forces the runtime to perform lots of 
>> work that it tries very hard to perform lazily otherwise. I would expect 
>> your measured cost to be much higher if you had linked to more high-level 
>> libraries (UIKit, MapKit, etc).
> 
> That was my gut reaction to the idea also, when I had it, but it seems to run 
> pretty fast no matter what I do. I just tried dragging every framework from 
> /System/Library/Frameworks into the project, removing only the Java 
> frameworks, Kernel.framework, Message.framework, and vecLib.framework. Time 
> taken was 0.004260 seconds.
> 
> It is, of course, ugly and hacky as hell, and that might make a pretty good 
> reason not to do it. :-/ What do you think about the other idea, of adding to 
> NSObject’s default implementation of +resolveInstanceMethod:? That *would* be 
> done lazily, and would avoid all the problems involving dynamically loaded 
> code.

Okay, here’s a more serious, less devil’s-advocatey sketch. It would require 
one tweak to the compiler to allow the swiftImplementationForSelector() method 
to be vtable dispatched. Otherwise, it pretty much works:

The basic protocol:

@objc protocol HasSwiftExtension {}

extension HasSwiftExtension {
// Problem: This method won't correctly be dispatched, and instead this 
implementation will always be called.
// The method cannot be declared in the protocol, because then Swift would 
try to use the Objective-C runtime
// to find it (and fail). Some way to declare methods in extensions that 
are dispatched via the vtable would
// need to be added for this to work properly.
func swiftImplementationForSelector(selector: Selector) -> (implementation: 
IMP, types: String)? {
return nil
}
}

extension NSObject {
class func somePrefixHere_SwizzledResolveInstanceMethod(selector: Selector) 
-> Bool {
// Doesn't work as written because of the lack of vtable dispatch.
// However, if you change "as? HasSwiftExtension" to "as? P" below, it 
will work in the case of P.
if let swiftySelf = self as? HasSwiftExtension {
// Yes, here we are calling an instance method from a class object.
// It works because the NSObject class is technically also an 
instance of NSObject.
// It would be better to use a class method, but Swift doesn't 
allow declaring those
// in protocols or extensions.
if let (implementation: imp, types: types) = 
swiftySelf.swiftImplementationForSelector(selector) {
class_addMethod(self, selector, imp, types)
return true
}
}

return somePrefixHere_SwizzledResolveInstanceMethod(selector)
}
}

The Objective-C shim to do the swizzling:

@interface NSObject(Swizzle)
@end

@implementation NSObject(Swizzle)

+ (void)load {
Method m1 = class_getClassMethod(self, @selector(resolveInstanceMethod:));
Method m2 = class_getClassMethod(self, 
@selector(somePrefixHere_SwizzledResolveInstanceMethod:));

method_exchangeImplementations(m1, m2);
}

@end

Sample protocol and class conforming to this:

// HasSwiftExtension conformance would be added automatically by the compiler.
@objc protocol P: HasSwiftExtension {
optional func foo() // optional only to avoid that compiler crash
}

class C: NSObject, P {}

extension P {
// This method wo

Re: [swift-evolution] [Rejected] SE-0009 Require self for accessing instance members

2016-01-06 Thread Charles Srstka via swift-evolution
> On Jan 6, 2016, at 1:34 PM, T.J. Usiyan <griotsp...@gmail.com> wrote:
> 
> On Wed, Jan 6, 2016 at 2:18 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
> I just spent a half hour last night debugging an issue that turned out to be 
> caused by something getting written to a property which I thought was being 
> written to a local variable, due to implicit self.
> 
> 
> One point to make is that requiring self is *not* the only fix for that 
> problem. You could also avoid shadowing. Which choice you make is up to you.

Avoiding shadowing (or avoiding anything else for that matter) is also possible 
to flub accidentally. There’s no optional warning about shadowing either, 
AFAICT.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Final by default for classes and methods

2015-12-20 Thread Charles Srstka via swift-evolution
I agree with this. -1 to the proposal.

Charles

> On Dec 17, 2015, at 8:00 PM, Rod Brown via swift-evolution 
>  wrote:
> 
> To play devils advocate, take for example UINavigationController in UIKit on 
> iOS.
> 
> I’ve seen multiple times in multiple projects legitimate reasons for 
> subclassing it, despite the fact that UIKit documentation says we “should not 
> need to subclass it”. So if we relied on Apple to “declare”, they most 
> probably wouldn’t, and these use cases (and some really impressive apps) 
> would become impossible.
> 
> While I agree with all points made about “If it’s not declared subclassable, 
> they didn’t design it that way”, I think that ties everyone’s hands too much. 
> There is a balance between safety and functionality that must be worked out. 
> I think this errs way too far on the side of safety.
> 
> Rod
> 
> 
>> On 18 Dec 2015, at 12:51 PM, Javier Soto > > wrote:
>> 
>> What if one framework provider thinks “you won’t need to subclass this ever”
>> 
>> If the framework author didn't design and implement that class with 
>> subclassing in mind, chances are it's not necessarily safe to do so, or at 
>> least not without knowledge of the implementation. That's why I think 
>> deciding that a class can be subclassed is a decision that should be made 
>> consciously, and not just "I forgot to make it final"
>> On Thu, Dec 17, 2015 at 5:41 PM Rod Brown > > wrote:
>> My opinion is -1 on this proposal. Classes seem by design to intrinsically 
>> support subclassing.
>> 
>> What if one framework provider thinks “you won’t need to subclass this ever” 
>> but didn’t realise your use case for doing so, and didn’t add the keyword? 
>> When multiple developers come at things from different angles, the 
>> invariable situation ends with use cases each didn’t realise. Allowing 
>> subclassing by default seems to mitigate this risk at least for the most 
>> part.
>> 
>> I think this definitely comes under the banner of “this would be nice” 
>> without realising the fact you’d be shooting yourself in the foot when 
>> someone doesn’t add the keyword in other frameworks and you’re annoyed you 
>> can’t add it.
>> 
>> 
>> 
>>> On 18 Dec 2015, at 10:46 AM, Javier Soto via swift-evolution 
>>> > wrote:
>>> 
>> 
>>> Does it seem like there's enough interesest in this proposal? If so, what 
>>> would be the next steps? Should I go ahead and create a PR on the evolution 
>>> repo, describing the proposal version that Joe suggested, with classes 
>>> closed for inheritance by default outside of a module?
>>> 
>>> Thanks!
>>> 
>>> On Tue, Dec 8, 2015 at 7:40 AM Matthew Johnson via swift-evolution 
>>> > wrote:
>>> I understand the rationale, I just disagree with it.
>>> 
>>> IMO adding a keyword to state your intention for inheritance is not a 
>>> significant obstacle to prototyping and is not artificial bookkeeping.  I 
>>> really don't understand how this would conflict with "consequence-free" 
>>> rapid development.  It is a good thing to require people to stop and think 
>>> before using inheritance.  Often there is a more appropriate alternative.
>>> 
>>> The assumption that it is straightforward to fix problems within a module 
>>> if you later decide you made a mistake is true in some respects but not in 
>>> others.  It is not uncommon for apps to be monolithic rather than being 
>>> well factored into separate modules, with many developers contributing and 
>>> the team changing over time.  While this is not ideal it is reality.
>>> 
>>> When you have the full source it is certainly *possible* to solve any 
>>> problem but it is often not straightforward at all.  Here is an example of 
>>> a real-work scenario app developers might walk into:
>>> 
>>> 1) A class is developed without subclassing in mind by one developer.
>>> 2) After the original developer is gone another developer adds some 
>>> subclasses without stopping to think about whether the original developer 
>>> designed for subclassing, thereby introducing subtle bugs into the app.
>>> 3) After the second developer is gone the bugs are discovered, but by this 
>>> time there are nontrivial dependencies on the subclasses.
>>> 4) A third developer who probably has little or no context for the 
>>> decisions made by previous developers is tasked with fixing the bugs.
>>> 
>>> This can be quite a knot to untangle, especially if there are problems 
>>> modifying the superclass to properly support the subclasses (maybe this 
>>> breaks the contract the superclass has with its original clients).
>>> 
>>> It may have been possible to avoid the whole mess if the second developer 
>>> was required to add 'inheritable' and 'overrideable' keywords or similar.  
>>> They are 

Re: [swift-evolution] [Proposal idea] Improved interop for ErrorType->NSError

2015-12-20 Thread Charles Srstka via swift-evolution
> On Dec 20, 2015, at 3:14 AM, Brent Royal-Gordon  
> wrote:
> 
> Anyway, my point remains: this _SwiftNativeNSError should use a userInfo 
> property on your ErrorType to populate NSError.userInfo. There should be no 
> need to go through the full rigamarole of calling NSError's initializer 
> yourself—just return a dictionary at the appropriate moment.

Having a userInfo property by which I could return the dictionary would work 
fine, and I’d be perfectly happy with it. I’m not sure if the Swift team would 
be happy with such a solution, though, since it necessarily involves 
dynamically typed objects, whereas my proposal enforces the correct types for 
all of the individual objects within the userInfo dictionary; String for the 
failure reason, NSURL for the URL, [String] for the recovery options, etc.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Final by default for classes and methods

2015-12-23 Thread Charles Srstka via swift-evolution
> On Dec 23, 2015, at 1:12 PM, Felipe Cypriano via swift-evolution 
>  wrote:
> 
> On Wed, Dec 23, 2015, at 09:25, Tino Heth wrote:
>> 
>>> The benefits of it far out weight the fears of having it.
>> so what is the practical problem that's solved by final that convinced you?
> 
> I like to make those kind of questions to make people think about it
> with an open mind. Currently the way I'm seeing it, the arguments
> against it are mostly based on fear of change. It feeling that it could
> be applied to other things in Swift like strong types "I hate that can't
> just call this method on this AnyObject instance"; or access control "I
> can't just perform selector on a private method anymore”.

Or “I’ve had to work with other people’s C++ code before, and I know what a 
PITA it is when there’s an issue you could easily solve by subclassing and 
overriding a few methods, but the library author, lacking ESP and knowledge of 
the future, didn’t anticipate that use case.” Surely I can’t be the only one 
that’s happened to.

But don’t get me wrong, this proposal can work all right just as long as we get 
rid of all human developers from all library and framework projects, and hire 
God to do them instead. I wonder how much he charges?

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] Require self for accessing instance members

2015-12-19 Thread Charles Srstka via swift-evolution
> On Dec 19, 2015, at 12:23 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> On Dec 19, 2015, at 3:02 AM, Tino Heth <2...@gmx.de <mailto:2...@gmx.de>> 
>> wrote:
>> 
>> imho the most valuable vote for mandatory self, just one comment on it 
>> 
>>> 1) Accessing a property, in a class, is more expensive than accessing a 
>>> local variable. The above code would require three message sends and/or 
>>> vtable accesses instead of one, if it were not assigning the property to a 
>>> local variable. These unnecessary property accesses needlessly reduce the 
>>> efficiency of the program.
>> True for Objective-C, and might be true for Swift in many cases as well - 
>> but just because of legacy reasons:
>> Correct me if I'm wrong, but I expect that simple getters have no 
>> performance penalty at all.
> 
> If a property isn’t marked final, it can be overridden by a subclass. That 
> suggests to me that a vtable lookup is necessary at the very least. Keep in 
> mind also that the property may be computed (and if it’s not, it might 
> *become* a computed property at some point in the future), in which case the 
> performance penalty could be *anything*. It could be an atomic property which 
> takes a lock every single time it’s accessed. It could run some complex 
> computation involving a host of other properties which themselves have 
> unknown costs. It could even be doing something like loading something off 
> the disk each time. Unless you have the source, you just don’t know. (And 
> even if you *do* have the source, hunting down every single access of the 
> property in the future won’t be fun if it becomes necessary to make the 
> property computed in the future).
> 
> IMHO, best practice is to load the property once and then use the result of 
> that, instead of spamming the getter over and over and over.

Another thing worth keeping in mind is that Apple has stated interest in fixing 
the fragile base-class problem in Swift (as, indeed, they will need to if it is 
to be usable as a framework language). However they solve this, it will have to 
create some kind of layer of indirection indirection when accessing instance 
members of classes (and possibly even structs, if they decide that framework 
authors should have the flexibility to add things to those as well). A small 
penalty, but still one to be aware of.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Proposal idea] Improved interop for ErrorType->NSError

2015-12-19 Thread Charles Srstka via swift-evolution
This is a bit of a pre-proposal; I wanted to bounce some ideas off the 
community before writing up a formal proposal, to see how people felt about 
this.

The Problem:

Swift introduces the very nifty ErrorType protocol, which, if implemented as an 
enum, allows one to associate arguments with the specific error cases with 
which they are relevant, as in this example:

enum MyError: ErrorType {
case JustFouledUp
case CouldntDealWithFile(url: NSURL)
case CouldntDealWithSomeValue(value: Int)
}

This is great, because it ensures that the file-related error will always have 
a URL object, whereas it won’t be included in the cases where it is irrelevant.

Unfortunately, the Cocoa APIs needed to display an error object to the user all 
take NSErrors, and the conversion from other ErrorTypes to NSErrors is not very 
good; using “as NSError” to convert a MyError will result in something that has 
all of the associated values removed, and the message displayed to the user 
will be a cryptic and not particularly user-friendly “MyError error 1” rather 
than something more descriptive. One can define an “toNSError()” method on 
one’s own error type that will properly propagate the NSError’s userInfo 
dictionary such that it will be displayed in a more meaningful way:

enum MyError: ErrorType {
case JustFouledUp
case CouldntDealWithFile(url: NSURL)
case CouldntDealWithSomeValue(value: Int)

func toNSError() -> NSError {
var userInfo = [String : AnyObject]()
let code: Int

switch self {
case .JustFouledUp:
userInfo[NSLocalizedFailureReasonErrorKey] = "Something fouled up!"
code = 0
case let .CouldntDealWithFile(url):
userInfo[NSLocalizedFailureReasonErrorKey] = "Something went wrong 
with the file \(url.lastPathComponent ?? "(null)")."
userInfo[NSURLErrorKey] = url
code = 1
case let .CouldntDealWithSomeValue(value):
userInfo[NSLocalizedFailureReasonErrorKey] = "This value isn't 
legit for some reason: \(value)"
code = 2
}

return NSError(domain: "MyError", code: code, userInfo: userInfo)
}
}

However, since this method will only be invoked if called explicitly, one has 
to make sure to include .toNSError() every time when throwing an error object, 
or else it will not display properly; one can never just throw a MyError 
object. This is error-prone (no pun intended), and also prevents things like 
making the error conform to Equatable and comparing it against an ErrorType we 
received from some other method.

I propose an addition to the ErrorType protocol, provisionally entitled 
“toNSError()”, but which another name could be given if something else is 
determined to be more appropriate. This method would be called by the system 
whenever “as NSError” is called on something that implements ErrorType. While 
this method would be added to the protocol, a default implementation would be 
provided in an extension, so that implementers of ErrorType would never 
actually need to override it unless very specific customization was required. 
For this default implementation, several other properties corresponding to some 
of the more commonly-used NSError keys (defined with default implementations 
returning nil) would be defined and referenced, and anything that returned 
non-nil would be packaged into a userInfo dictionary, like so:

protocol ErrorType {
var description: String? { get }
var failureReason: String? { get }
var recoverySuggestion: String? { get }
var recoveryOptions: [String]? { get }
var recoveryAttempter: AnyObject? { get }
var helpAnchor: String? { get }
var underlyingError: ErrorType? { get }
var URL: NSURL? { get }

func toNSError() -> NSError
}

extension ErrorType {
var description: String? { return nil }
var failureReason: String? { return nil }
var recoverySuggestion: String? { return nil }
var recoveryOptions: [String]? { return nil }
var recoveryAttempter: AnyObject? { return nil }
var helpAnchor: String? { return nil }
var underlyingError: ErrorType? { return nil }
var URL: NSURL? { return nil }

func toNSError() -> NSError {
let domain = // do what “as NSError” currently does to generate the 
domain
let code = // do what “as NSError” currently does to generate the code

var userInfo = [String : AnyObject]()

if let description = self.description {
userInfo[NSLocalizedDescriptionKey] = description
}

if let failureReason = self.failureReason {
userInfo[NSLocalizedFailureReasonErrorKey] = failureReason
}

if let suggestion = self.recoverySuggestion {
userInfo[NSLocalizedRecoverySuggestionErrorKey] = suggestion
}

if let options = self.recoveryOptions {

Re: [swift-evolution] Brace syntax

2015-12-19 Thread Charles Srstka via swift-evolution
> On Dec 19, 2015, at 7:39 PM, Alexander Regueiro via swift-evolution 
>  wrote:
> 
> Has anyone considered removing braces from the Swift language? The main 
> alternative would be indentation-based scoping like in Python or Ruby.

No. No no no no no no no. No. Please, no.

-1.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal idea] Improved interop for ErrorType->NSError

2015-12-20 Thread Charles Srstka via swift-evolution
> On Dec 20, 2015, at 12:35 AM, Brent Royal-Gordon  
> wrote:
> 
> I don't know if it can actually be private, but it should be invisible to 
> developers, and considered an implementation detail. It might also make sense 
> to retrieve the `userInfo` from `swiftError` on demand—the exact 
> implementation isn't very important here.

Whatever the solution is, it shouldn’t be invisible to developers. We need a 
good way to get non-NSError ErrorTypes to turn into NSErrors that have decently 
propagated userInfo dictionaries, so that they can be presented to the user in 
a form that isn’t just a cryptic “ error ”.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] rename dropFirst() and dropLast()

2015-12-28 Thread Charles Srstka via swift-evolution
> On Dec 28, 2015, at 6:19 PM, Michel Fortin via swift-evolution 
>  wrote:
> 
> Really? The convention says: "When a mutating method is described by a verb, 
> name its non-mutating counterpart according to the “ed/ing” rule, e.g. the 
> non-mutating versions of x.sort() and x.append(y) are x.sorted() and 
> x.appending(y)."

That’s really ironic, given that sort() on Array in the standard library is the 
non-mutating version (the mutating version is called sortInPlace).

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal idea] Improved interop for ErrorType->NSError

2015-12-21 Thread Charles Srstka via swift-evolution
> On Dec 21, 2015, at 5:36 PM, Colin Cornaby  wrote:
> 
> So here’s my 2 cents. I talked to Charles about this off list, so I’ll just 
> say my piece and then move along. :)
> 
> It seems to me that ErrorType is very empty because it’s meant to be a 
> placeholder in the language for whatever the native error type is on the 
> platform. When I’m in AppKit/UIKit/OSS Swift Foundation, I’m using NSError. 
> When I’m using C API, my ErrorType would probably be a typedef’d int. When 
> I’m using Win32, my ErrorType is whatever Win32 error types are. If I’m using 
> Swift with some platform/API where the error types are some sort of struct, 
> or even a string type, those types can be made to conform to error type. It’s 
> meant to be a shallow wrapper because it’s just a placeholder to wrap the 
> native platform API.
> 
> I’m not sure I like going down the path of Swift actually trying to replace 
> platform API, especially if it requires a hand bridge. Then you’re constantly 
> extending the language to bridge the error types from all the different 
> platforms. My view is that OSS Swift Foundation provides a template where the 
> platform API cannot be assumed, and that OSS Swift Foundation defines it’s 
> own concrete error type in NSError/Error. Certainly NSError isn’t perfect and 
> the conversation on how to make it better is worthwhile (especially now that 
> NSError is part of Swift Foundation, and changes could also be adopted by 
> Obj-C Foundation where relevant.)
> 
> A year ago my opinion on this was very different, and I was bothering people 
> on the Swift team for a similar improvement based on where Swift was at the 
> time. But with OSS Foundation and multiplatform Swift my feeling has changed. 
> I’m not comfortable with trying to promote NSError concepts higher into the 
> language when I think Swift conforming to the host platform’s error API is 
> the better path. My assumption is that Swift is not meant to be a platform in 
> itself (like Java), but just a language over an existing platform.

And my two cents is:

NSError is antiquated, and enums conforming to ErrorType, with associated types 
on the case values, are much better. They are cleaner, they are easier to use, 
and they are nicer to look at.

Creating them is nicer:

let error = MyError.FileNotFound(url: someURL)

vs.

var userInfo: [String : AnyObject] = [NSLocalizedFailureReason : “The file 
\(someURL.lastPathComponent ?? “(null)”) could not be found.”, NSURLErrorKey : 
someURL]
if someURL.fileURL, let path = someURL.path { userInfo[NSFilePathErrorKey] = 
path }
let error = NSError(domain: “SomeArbitraryString”, code: 
Int(ErrorCodeEnum.FileNotFound.rawValue), userInfo: userInfo)

Comparing them is nicer:

if case let .FileNotFound(url) = error {
// handle the error
}

vs.

if error.domain == “SomeArbitraryString” && error.code == 
Int(ErrorCodeEnum.FileNotFound.rawValue) {
let url: NSURL

if let theURL = error.userInfo[NSURLErrorKey] as? NSURL {
url = theURL
} else if let path = error.userInfo[NSFilePathErrorKey] as? String {
url = NSURL(fileURLWithPath: path)
} else {
// handle not having a url, and bail out
}

// now handle the error
}

I don’t think any further explanation is necessary. :-P

The only real problem with ErrorType is sending it to legacy AppKit APIs that 
expect an NSError, since there’s no way to customize what happens when the user 
converts one of them via “as NSError”. You have to write your own conversion 
method, and then be scrupulous about always calling that instead of “as 
NSError”, which is particularly problematic if you receive the error as a plain 
ErrorType without knowing that it’s your particular error type, in which case 
you have to do runtime type checking to see if you should use the custom 
conversion method or the built-in “as NSError” conversion.

If this could be fixed, it’d be fantastic.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Final by default for classes and methods

2015-12-23 Thread Charles Srstka via swift-evolution
The frameworks remaining useful simply because they happen to be written in a 
different language would be a pretty sad state of affairs, IMO.

Charles

> On Dec 23, 2015, at 1:30 PM, Felipe Cypriano  wrote:
> 
> Sounds like you are going to continue using Objective-C until you can get God 
> on your team.
>  
>  
> On Wed, Dec 23, 2015, at 11:23, Charles Srstka wrote:
>>> On Dec 23, 2015, at 1:12 PM, Felipe Cypriano via swift-evolution 
>>> > wrote:
>>>  
>>> On Wed, Dec 23, 2015, at 09:25, Tino Heth wrote:
  
> The benefits of it far out weight the fears of having it.
 so what is the practical problem that's solved by final that convinced you?
>>>  
>>> I like to make those kind of questions to make people think about it
>>> with an open mind. Currently the way I'm seeing it, the arguments
>>> against it are mostly based on fear of change. It feeling that it could
>>> be applied to other things in Swift like strong types "I hate that can't
>>> just call this method on this AnyObject instance"; or access control "I
>>> can't just perform selector on a private method anymore”.
>> 
>> Or “I’ve had to work with other people’s C++ code before, and I know what a 
>> PITA it is when there’s an issue you could easily solve by subclassing and 
>> overriding a few methods, but the library author, lacking ESP and knowledge 
>> of the future, didn’t anticipate that use case.” Surely I can’t be the only 
>> one that’s happened to.
>>  
>> But don’t get me wrong, this proposal can work all right just as long as we 
>> get rid of all human developers from all library and framework projects, and 
>> hire God to do them instead. I wonder how much he charges?
>>  
>> Charles
>>  
>  

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pre-proposal: Convert reference params to tuples

2015-12-23 Thread Charles Srstka via swift-evolution
> On Dec 23, 2015, at 5:11 AM, Tino Heth <2...@gmx.de> wrote:
> 
> Imho it sounds good, but I rarely encounter situations where I would benefit 
> from the proposed change…

It does happen in the Objective-C frameworks; the NSURL example I provided is 
an aggravatingly common one, but there are plenty others (particularly anything 
that begins with “get”). In C, of course, it’s all over the place.

It would be handy for third-party code, as well. I’m currently converting a 
class hierarchy from Obj-C to Swift that returns multiple values, but since 
this code still has to be interoperable with Obj-C (for now), I can’t move it 
to returning a tuple yet, and all these UnsafeMutablePointers are driving me 
*crazy*.

> and afair "out" is an Objective-C addition, so there would be no improvement 
> for plain C.

While that’s true, Apple could use the same sort of solution that they have 
done in many other places; just use #ifdef checks to #define some constant like 
NS_OUT to ‘out’ for Objective-C, and to an empty string otherwise.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Final by default for classes and methods

2015-12-23 Thread Charles Srstka via swift-evolution
> On Dec 23, 2015, at 8:15 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> I’m not trying to force my opinion on anyone.  I’m just making a case for the 
> advantages of a particular default.  Changing the default does not break 
> inheritance at all.  Nobody has to use the default when it doesn’t fit the 
> design they wish to implement. 

I disagree; changing the default will largely break inheritance, because hardly 
anything (in pure-Swift frameworks; I know that Obj-C will still be what it is) 
will be overridable anymore, unless the framework author specifically 
anticipated your use case. Which when we’re dealing with human developers, 
isn’t necessarily going to be the case.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Pitch: Deinit for structs

2015-12-23 Thread Charles Srstka via swift-evolution
Introduction:

This is a rather simple proposal, requesting that structs allow the ‘deinit’ 
destructor, as classes currently do.

Motivation:

Sometimes it is necessary to create an object that wraps a network connection 
(that needs to be closed when the object is destroyed), or that writes to a 
file on the disk (that has to be closed when the object is destroyed). Often 
these objects will implement a close() method, but in the case that the user 
forgets to call this before the object is disposed of, it is good to call it in 
deinit just in case. However, deinit currently is available only to classes and 
not to structs. This means that value types currently cannot be used for 
network and file-backed constructs. Given Swift’s emphasis on value types, it 
seems that it would be good to add this functionality to value types.

Proposed Solution:

Allow the deinit destructor in structs.

Impact on Existing Code:

Should be no impact on existing code.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Pitch: Copy constructors for structs

2015-12-23 Thread Charles Srstka via swift-evolution
Introduction:

This is a request for a copy constructor mechanism for structs in Swift.

Motivation:

Suppose you have a class stored inside a struct, like so:

class C {
func copy() -> C { … }
}

struct S {
var i: Int
var c: C
}

and you create a couple of the structs, like so:

let c = C()
let foo = S(i: 1, c: c)
var bar = foo
bar.i = 2

Since the ‘bar’ variable was mutated, it now contains a copy of the original 
‘foo’ struct. However, both structs still carry the same pointer to ‘c'. There 
may be cases where you would want a copy of the struct to make a copy of any 
reference types stored within; however, that does not seem to be possible 
currently.

Proposed Solution:

Adding a copy constructor to S that would be called when a copy of the struct 
is about to be made. This constructor would simply create a new instance, 
initialize it, and return it. The copy constructor would look like this:

struct S {
var i: Int
var c: C

copy {
return S(i: self.i, c: self.c.copy())
}
}

Structs that do not implement the copy constructor would get the same behavior 
as they do currently.

Impact on Existing Code:

There should be no impact on existing code that does not implement the copy 
constructor.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: One-past-end array pointers and convertibility of nil for interaction with C APIs

2015-12-23 Thread Charles Srstka via swift-evolution
> On Dec 23, 2015, at 7:50 PM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> The & operator isn't exactly an address-of operator. Does [0] even return 
> a pointer to the inner buffer? When you use & with properties (and possibly 
> with subscripts as well), Swift may create a local, copy the property value 
> to it, pass a pointer to that local, and copy back the output to the property.
> 
> Anyway, you are probably looking for Array.withUnsafe(Mutable?)BufferPointer:
> 
> arr.withUnsafeMutableBufferPointer { foo($0, $0.count) }
> 
> Félix

The comments in the generated header for UnsafeMutablePointer claim that its 
regular init() method constructs a null pointer. Therefore, I think you should 
just be able to:

foo(UnsafeMutablePointer(), 0)

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Charles Srstka via swift-evolution
MOTIVATION:

As per the current situation, there is a pitfall when writing asynchronous APIs 
that does not occur when writing synchronous APIs. Consider the following 
synchronous API:

func doSomething() -> SomeEnum {
if aCondition {
if bCondition {
return .Foo
} else {
return .Bar
}
} else {
if cCondition {
return .Baz
}
}
}

The compiler will give an error here, since if both aCondition and cCondition 
are false, the function will not return anything.

However, consider the equivalent async API:

func doSomething(completionHandler: (SomeEnum) -> ()) {
dispatch_async(someQueue) {
if aCondition {
if bCondition {
completionHandler(.Foo)
} else {
completionHandler(.Bar)
}
} else {
if cCondition {
completionHandler(.Baz)
}
}
}
}

Whoops, now the function can return without ever firing its completion handler, 
and the problem might not be discovered until runtime (and, depending on the 
complexity of the function, may be hard to find).

PROPOSED SOLUTION:

Add a @required attribute that can be applied to closure arguments. This 
attribute simply states that the given closure will always be eventually 
called, and the compiler can enforce this.

DETAILED DESIGN:

- The @required attribute states in our API contract that a given closure 
*must* be called at some point after the function is called.

- Standard API calls like dispatch_async that contractually promise to execute 
a closure or block get @required added to their signatures.

- When the compiler sees a @required closure in a function declaration, it 
checks to make sure that every execution path either calls the closure at some 
point, or sends a @required closure to another API that eventually ends up 
calling the closure.

- If there’s a way for a @required closure not to be called, the compiler emits 
an error letting the developer know about the bug in his/her code.

IMPACT ON EXISTING CODE:

None. This is purely additive.

ALTERNATIVES CONSIDERED:

I got nothin’.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Charles Srstka via swift-evolution
> On Jun 5, 2016, at 10:28 AM, Michael Peternell  
> wrote:
> 
> This is not a good design. If you want the completion handler to be called, 
> you can rewrite the function to make this intent obvious:
> 
> func doSomethingAsync(completionHandler: (SomeEnum) -> ()) {
>dispatch_async(someQueue) {
>let result = doSomething()
>completionBlock(result)
>}
> }
> 
> func doSomething() -> SomeEnum {
>if aCondition {
>if bCondition {
>return .Foo
>} else {
>return .Bar
>}
>} else {
>if cCondition {
>return .Baz
>}
>}
> }
> 
> and this begs the question why the doSomethingAsync() function is needed at 
> all.. Calling dispatch_async directly is probably more convenient and the 
> abstraction of doSomething() probably not that useful.. (I know the example 
> is overly simplistic, but I can apply the same reasoning to more complex 
> scenarios just as easily too.)
> 
> IMHO, asynchronous programming is only a good thing when used in moderation. 
> In most cases that I see, it just makes everything harder to reason about. 
> For most applications, it's best to have one UI thread and one worker thread. 
> This leads to code that is debuggable, testable and inspectable. For example, 
> it wouldn't help a C compiler if it can use multiple threads to compile a 
> file; usually you have much more files to compile than cores, so you can let 
> `make` do the scheduling. Concurrency-management code and application code 
> should never be mixed, as much as possible and practical. Asynchronous code 
> violates this principle regularly.
> 
> assert(async programming == Goto 2.0)

Well, the example I gave *was* deliberately simplistic; there are many cases 
where the code needs to call APIs which themselves are asynchronous. If the 
purpose of doSomething() is to grab something from the network, and then do 
something with it, then it’s going to be using async APIs under the hood if 
you’re doing it the recommended way. Similarly, if the method grabs something 
from another task using XPC, that’s asynchronous. Pop up a sheet to ask the 
user for feedback before continuing? Asynchronous. NSUserScriptTask? 
Asynchronous. Yeah, you can use a dispatch semaphore to hack these async APIs 
into synchronous ones, but then you’re violating Apple’s recommendation about 
never blocking dispatch queues.

Anyway, I don’t think asynchronous APIs are going away any time soon, and it 
would be nice if it were easier to safely write them.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Change @noreturn to unconstructible return type

2016-06-05 Thread Charles Srstka via swift-evolution
> On Jun 5, 2016, at 1:49 PM, Pyry Jahkola via swift-evolution 
>  wrote:
> 
> 
>> On 05 Jun 2016, at 21:26, Антон Жилин via swift-evolution 
>> > wrote:
>> 
>> The following names were suggested: NoReturn, Bottom, None, Never.
>> I would pick None, because it looks like opposite to Any and fits nicely in 
>> generic types.
> 
> I would pick `Never` because `None` would overload the notion of a returnable 
> nothingness with its antonym!
> 
> OTOH, "never" is quite unlikely to be a type name in user code, likely pretty 
> googleable, and explains itself quite well in examples like `Result Never>`.
> 
>> I would prefer the type to be simple, and be implemented as a case-less enum 
>> (not a bottom value, as in Haskell).
>> 
>> None should be a usual enum, with no compiler magic except that functions 
>> returning None are equivalent to current @noreturn.
> 
> I think it would be more useful if the compiler allowed `Never` in every type 
> context (i.e. whatever type `T` was expected, an expression of type `Never` 
> would be allowed), making expressions like the following compile:
> 
> let unwrapped: Int = optional ?? fatalError("explanation why this must 
> not happen")
> 
> — Pyry

I dunno, I think @noreturn is clearer than any of these. It tells you that the 
function… won’t return. None, Never, etc. could be mistaken as a synonym for 
Void, whereas @noreturn is pretty hard to miss.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Change @noreturn to unconstructible return type

2016-06-07 Thread Charles Srstka via swift-evolution
> On Jun 7, 2016, at 3:12 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Jun 7, 2016 at 2:49 PM, Michael Peternell via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
> > Am 07.06.2016 um 19:45 schrieb Charles Srstka via swift-evolution 
> > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
> >
> >> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution 
> >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> >>
> >>> I disagree. We are discussing how to annotate a function in some way so 
> >>> that the compiler knows that the code following it will never be executed 
> >>> *and* so a human who reads the declaration knows that it does not return. 
> >>> “Never" is a poor choice for that. Never what? Never return? Never use 
> >>> this function? Never say never again?
> >>
> >> "Never return". That's why it's in the return type slot, right after the 
> >> `->`. If you read it out loud, you'll read "returns Never", which is 
> >> exactly correct.
> >>
> >> NoReturn, on the other hand, does *not* read well in that slot: "returns 
> >> NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes 
> >> no sense whatsoever *as a type name*.
> >
> > But it’s *not* a type. You’ll never have an instance of it.
> 
> That's the dictionary definition of a bottom type 
> <https://en.wikipedia.org/wiki/Bottom_type>, though: a type which has no 
> values.
>  
> Since it’s not a type name, it doesn’t make sense that it needs to look like 
> one. What it is doing is telling you something about the behavior of the 
> function itself, not its return value. Its return value, if there were one, 
> is irrelevant, since the function, by its very nature, will never even get to 
> the point where it would return it.
> 
> And that's the dictionary definition of a function where the return type is 
> bottom. This isn't something being made up just for Swift...

What’s the dictionary definition of a do loop? Or a for loop? Or try/catch?

Swift doesn’t do things the same as other languages in lots of places. I don’t 
see why it has to be different here. @noreturn is a clearer description of what 
this construct does.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Change @noreturn to unconstructible return type

2016-06-07 Thread Charles Srstka via swift-evolution
> On Jun 7, 2016, at 3:56 PM, Xiaodi Wu  wrote:
> 
> No doubt, @noreturn is clearer today, but how much of that is because it's 
> what we already know?

None. It’s clearer because it does exactly what it says on the tin. Show it to 
someone who’s familiar with the concept of functions and returning but who's 
never seen Swift before, and they will intuit what it does.

> And FWIW, "returns never" is hard to misinterpret, no?

“returns never” isn’t what you have, though. You have func foo() -> Never, 
which could mean a bunch of things. It could mean it never returns a *value*, 
i.e. a void return. It could mean someone made some crazy struct and named it 
Never. It’s not obvious from looking at it without prior knowledge of the 
system.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-06 Thread Charles Srstka via swift-evolution
On Jun 6, 2016, at 2:49 PM, Michael Peternell  wrote:
> 
> That's really hard to answer in the general case. I think real proposals 
> should contain concrete, realistic examples that show the benefit of the 
> proposal. It's really hard to argue against a proposal if there is no such 
> example. User feedback from a sheet is one of the few examples where 
> asynchronous programming makes sense: But I cannot see how a `@required` 
> annotation would be useful in that setting.

Quick-n-dirty example, written in Mail. How would you make this synchronous?

import Foundation

enum Result {
case success(T)
case error(ErrorType)
}

enum MyError: ErrorType {
case unknownError
case corruptData
case badStatusCode(Int)
}

struct SomeThing {
init?(data: NSData) {
...
}
}

func getSomethingFromTheNetwork(url: NSURL, completionHandler: 
(Result) -> ()) { 
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, 
response, error in
if let error = error {
completionHandler(.error(error))
return
}

if let httpResponse = response as? NSHTTPURLResponse {
let statusCode = httpResponse.statusCode

if statusCode < 200 || statusCode >= 300 {

completionHandler(.error(MyError.badStatusCode(statusCode)))
return
}
}

guard let data = data else {
completionHandler(.error(MyError.unknownError))
return
}

guard let something = SomeThing(data: data) else {
completionHandler(.error(MyError.corruptData))
return
}

completionHandler(.success(something))
}

task.resume()
}

(disclaimer: yes, we’d probably have to improve the API for NSURLSession a bit 
here for @required to be useful.)

How would you make this synchronous:

func getSomethingFromAnotherTask(completionHandler: (Result) -> ()) {
let message = ...

xpc_send_message_with_reply(self.connection, message, 
self.dispatchQueue) { reply in
do {
let something = try 
self.turnReplyIntoSomethingSomehow(reply)

completionHandler(.success(something))
} catch {
completionHandler(.error(error))
}
}
}

Or this:

func doSomethingThatNeedsUserInput(completionHandler: (Bool) -> ()) {
let alert = NSAlert()

alert.messageText = “Should we continue?”
alert.addButtonWithTitle(“Continue”)
alert.addButtonWithTitle(“Cancel”)

alert.beginSheetModalForWindow(someWindow) { response in
if response == NSAlertFirstButtonReturn {
completionHandler(true)
}

// uh oh, I forgot to test for other conditions, and now the 
completion handler won’t be called if the user clicked “Cancel”.
// Too bad the compiler couldn’t warn me about it.
}
}

There are some tasks which synchronous programming is simply not well-suited 
for.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-06 Thread Charles Srstka via swift-evolution
> On Jun 6, 2016, at 3:48 PM, michael.petern...@gmx.at wrote:
> 
> Yes, ok...
> 
> Well, I cannot easily make everything synchronous. I just can change it in a 
> way that makes a `@required` attribute "optional" ;)
> 
> import Foundation
> 
> enum Result {
>case success(T)
>case error(ErrorType)
> }
> 
> enum MyError: ErrorType {
>case unknownError
>case corruptData
>case badStatusCode(Int)
> }
> 
> struct SomeThing {
>init?(data: NSData) {
>...
>}
> }
> 
> func getSomethingFromTheNetwork(url: NSURL, completionHandler: 
> (Result) -> ()) { 
>func toSomeThing(data: NSData?, response: NSURLResponse?, error: NSError?) 
> -> Result {
>if let error = error {
>return .error(error)
>}
> 
>if let httpResponse = response as? NSHTTPURLResponse {
>let statusCode = httpResponse.statusCode
> 
>if statusCode < 200 || statusCode >= 300 {
>return .error(MyError.badStatusCode(statusCode))
>}
>}
> 
>guard let data = data else {
>return .error(MyError.unknownError)
>}
> 
>guard let something = SomeThing(data: data) else {
>return .error(MyError.corruptData)
>}
> 
>return .success(something)
>}
>let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, 
> response, error in
>completionHandler(toSomething(data, response, error))
>}
> 
>task.resume()
> }

I’ve written code like that; however, it falls down as soon as you have to nest 
two or more asynchronous APIs. Consider the following, and assume we don’t have 
control of SomeThing’s API (or, maybe, SomeThing relies on some other API we 
don’t control that has to be asynchronous):

import Foundation

enum Result {
   case success(T)
   case error(ErrorType)
}

enum MyError: ErrorType {
   case unknownError
   case corruptData
   case badStatusCode(Int)
}

struct SomeThing {
   make(data: NSData, completionHandler: (SomeThing?) -> ())
}

func getSomethingFromTheNetwork(url: NSURL, completionHandler: 
(Result) -> ()) { 
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, 
response, error in
if let error = error {
completionHandler(.error(error))
return
}

if let httpResponse = response as? NSHTTPURLResponse {
let statusCode = httpResponse.statusCode

if statusCode < 200 || statusCode >= 300 {

completionHandler(.error(MyError.badStatusCode(statusCode)))
return
}
}

guard let data = data else {
completionHandler(.error(MyError.unknownError))
return
}

SomeThing.make(data) { something in
if let something = something {
completionHandler(.success(something))
} else {
completionHandler(.error(MyError.corruptData))
}
}
}

task.resume()
}

Yeah, you can wrap it in yet another function, but if things get complex 
enough, and you forget to do that somewhere, it’s bad news.

> With a semaphore, I can also make it synchronous. Not sure if this is a good 
> idea though... If the API is already asynchronous, it's probably better to 
> use it that way.

It’s not a good idea. As I mentioned before, Apple recommends against blocking 
on dispatch queues. It’s not considered good practice. That includes the main 
queue, by the way;  both Cocoa-Dev and Stack Overflow are filled with questions 
from people who tried using dispatch_sync or dispatch_async to the main queue 
to run -[NSOpenPanel runModal], and then got confused when nothing in the panel 
displayed properly. Using the async methods on NSOpenPanel and returning via a 
completion handler would have caused this to work properly.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Make `default` function parameter values more transparent

2016-06-13 Thread Charles Srstka via swift-evolution
> On Jun 12, 2016, at 11:27 PM, Charlie Monroe via swift-evolution 
>  wrote:
> 
>> 
>> On Jun 11, 2016, at 3:35 PM, Adrian Zubarev via swift-evolution 
>> > wrote:
>> 
>> I just installed the current Swift 3 snapshot to play around with it (last 
>> from may crashed my Xcode all the time).
>> 
>> I wanted to re-build a small project with (currently implemented) Swift 3 
>> changes. Basically I had to look up on GitHub what the default value for 
>> deinitialize(count:) function was for UnsafeMutablePointer, just because 
>> Xcode and the docs can’t tell me that:
>> 
>> /// De-initialize the `count` `Pointee`s starting at `self`, returning
>> /// their memory to an uninitialized state.
>> ///
>> /// - Precondition: The `Pointee`s at `self..> ///   initialized.
>> ///
>> /// - Postcondition: The memory is uninitialized.
>> public func deinitialize(count: Int = default)
>> To cut it short:
>> 
>> Could we make default function parameter values more transparent in Swift 3?
>> Why are default parameter values translated to default rather than the 
>> actual value?
> I guess that in some cases you don't want the default value to be known, or 
> is irrelevant. Most importantly, it can be a more complex expression - e.g. 
> creating an object and calling something on it:
> 
> private let mySecretNumber = 0x999
> public func deinitialize(count: Int = NSProcessInfo().processorCount + 
> mySecretNumber)
> 
> And that's a pretty example, it can get much nastier. Since mySecretNumber is 
> private, it definitely cannot be exposed.

That was my reaction as well, but this change is already in the pipeline, 
according to Apple’s published plans.

https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst#default-argument-expressions
 


Presumably, once this goes through, it will no longer be possible to use a 
secret number as a default value.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: @required attribute for closures

2016-06-05 Thread Charles Srstka via swift-evolution
> On Jun 5, 2016, at 5:46 PM, michael.petern...@gmx.at wrote:
> 
>> Am 05.06.2016 um 20:31 schrieb Charlie Monroe via swift-evolution 
>> >:
>> 
>> While I agree with Michael that nowadays, a lot of stuff that doesn't need 
>> to be, is done async, which leads to a giant thread pool per app and 
>> developers nowadays do not think of the cost of inter-thread communication 
>> (i.e. each dispatch_(a)sync has its cost, even though it's a light-weight 
>> thread), I agree with Charles that something like suggested does indeed help 
>> debugging issues with multi-thread apps.
>> 
> 
> I agree that it may help in a few cases. But I think the change is "not 
> significant enough to warrant a change in Swift". It adds yet another keyword 
> to the language that every new dev has to learn about, and the problem it 
> solves can more elegantly be solved by writing more elegant code.

Okay, what’s the “more elegant” way to write a function that uses networking or 
XPC, or that requires user feedback from a sheet?

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Change @noreturn to unconstructible return type

2016-06-07 Thread Charles Srstka via swift-evolution
> On Jun 7, 2016, at 11:47 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> I disagree. We are discussing how to annotate a function in some way so that 
>> the compiler knows that the code following it will never be executed *and* 
>> so a human who reads the declaration knows that it does not return. “Never" 
>> is a poor choice for that. Never what? Never return? Never use this 
>> function? Never say never again? 
> 
> "Never return". That's why it's in the return type slot, right after the 
> `->`. If you read it out loud, you'll read "returns Never", which is exactly 
> correct.
> 
> NoReturn, on the other hand, does *not* read well in that slot: "returns 
> NoReturn". Huh? I mean, I suppose you won't misunderstand it, but it makes no 
> sense whatsoever *as a type name*.

But it’s *not* a type. You’ll never have an instance of it. Since it’s not a 
type name, it doesn’t make sense that it needs to look like one. What it is 
doing is telling you something about the behavior of the function itself, not 
its return value. Its return value, if there were one, is irrelevant, since the 
function, by its very nature, will never even get to the point where it would 
return it. Either it’s going to kill the app via a fatalError or something, or 
we have something like dispatch_main() which will keep executing until the 
program stops, and one way or another, it won’t return.

For that reason, frankly, I don’t understand why we want to change this from 
being an attribute, which seems to me the more natural and logical choice to 
describe this behavior. If we *do* have to change it, though, NoReturn conveys 
the most clearly to the reader what it does.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Protected Access Level

2016-05-30 Thread Charles Srstka via swift-evolution
> On May 30, 2016, at 3:42 AM, Tino Heth via swift-evolution 
>  wrote:
> 
>> I can't reply directly to all the points in this thread, but I will just say 
>> that there are ways of emulating protected in the language as it exists 
>> today:
>> 
>> If the goal is to have functions that can be overridden by subclasses 
>> without being called by external classes, you can create a parameter of a 
>> public type with a private initializer and use it in all "protected" member 
>> functions. No external code will be able to call such functions because they 
>> cannot create an argument of the correct type.
> As others stated before:
> I agree it's a cool little hack, but a hack none the less — and imho it isn't 
> useful in real life.
> The focus should be documenting intend ("this method should be used in a 
> certain way"). Creating clever countermeasures to stop users of a library to 
> enforce limitations is imho the wrong way.

Couldn’t you use the same reasoning to claim there shouldn’t be access control 
at all? Just add documention on methods you want to mark private telling users 
of the library not to call them!

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Protected Access Level

2016-05-30 Thread Charles Srstka via swift-evolution
> On May 28, 2016, at 8:11 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> But `protected` is quite different from other access levels; it does not 
> limit the visibility of the symbols, but rather their use. And protocols face 
> the same sort of problem as classes, where certain members are essentially 
> override hooks and shouldn't be called directly outside a particular scope.
> 
> So I think we ought to allow `accesslevel(call)`, but not a plain 
> `accesslevel`:
> 
>   public fileprivate(call) func layoutSubviews()
>   internal fileprivate(call) func privateSubclassingHook()
>   public internal(set: call) var x = 20
>   internal(call) func protocolConformanceHook()
>   fileprivate(set: call) var onlyProtocolSetsThis: Int { get set }


Given that this is almost identical to the pitch I floated to the list some 
months ago, all the way down to the fileprivate(call) syntax (well, back then 
“fileprivate” was “private”, so it was private(call)), I’m +1 on this.

> On May 29, 2016, at 6:55 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> The thing is, though, the contents of the sharps drawer are *still* sharp 
> even if you're old enough to use a knife. And similarly, APIs like the 
> `state` setter are *still* dangerous even if you've subclassed 
> `UIGestureRecognizer`. To be sure, it is more likely that you'll *need* to 
> set `state`, but it's still not something you should do carelessly or without 
> understanding the consequences.


This, though, reads like “The 17-year-old might cut himself with a knife, even 
though he *needs* the knives to help with the cooking. So, let’s give knives to 
the newborn!”

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-31 Thread Charles Srstka via swift-evolution
A huge +1 on the syntax change, which I think is a colossal improvement over 
the current situation and adds a lot of clarity to enum declarations.

Neutral on the necessity to add actual stored properties to the enums. If the 
new syntax were merely syntactic sugar that would effectively generate the 
switch statements behind the scenes, that would work for me too, and would 
probably offend fewer people.

Charles

> On May 31, 2016, at 9:17 AM, Jānis Kiršteins via swift-evolution 
>  wrote:
> 
> I wrote a proposal draft:
> 
> # Enum case stored properties
> 
> * Proposal: TBD
> * Author: [Janis Kirsteins](https://github.com/kirsteins)
> * Status: TBD
> * Review manager: TBD
> 
> ## Introduction
> 
> This proposal allows each enum case to have stored properties.
> 
> ## Motivation
> 
> Enums cases can have a lot of constant (or variable) static values
> associated with it. For example, planets can have mass, radius, age,
> closest star etc. Currently there is no way to set or get those values
> easily.
> 
> Example below shows that is hard to read and manage static associated
> values with each case. It is hard to add or remove case as it would
> require to add or remove code in four different places in file. Also
> static associated value like `UIBezierPath` is recreated each time the
> property is computed while it's constant.
> 
> ```swift
> enum Suit {
>case spades
>case hearts
>case diamonds
>case clubs
> 
>var simpleDescription: String {
>switch self {
>case .spades:
>return "spades"
>case .hearts:
>return "hearts"
>case .diamonds:
>return "diamonds"
>case .clubs:
>return "clubs"
>}
>}
> 
>var color: UIColor {
>switch self {
>case .spades:
>return .blackColor()
>case .hearts:
>return .redColor()
>case .diamonds:
>return .redColor()
>case .clubs:
>return .blackColor()
>}
>}
> 
>var symbol: String {
>switch self {
>case .spades:
>return "♠"
>case .hearts:
>return "♥"
>case .diamonds:
>return "♦"
>case .clubs:
>return "♣"
>}
>}
> 
>var bezierPath: UIBezierPath {
>switch self {
>case .spades:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .hearts:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .diamonds:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .clubs:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>}
>}
> }
> ```
> 
> ## Proposed solution
> 
> Support stored properties for enum cases just as each case were an
> instance. Case properties are initialized block after each case
> declaration.
> 
> ```swift
> enum Suit {
>let simpleDescription: String
>let color: UIColor
>let symbol: String
>let bezierPath: UIBezierPath
> 
>case spades {
>simpleDescription = "spades"
>color = .blackColor()
>symbol = "♠"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case hearts {
>simpleDescription = "hearts"
>color = .redColor()
>symbol = "♥"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case diamonds {
>simpleDescription = "diamonds"
>color = .redColor()
>symbol = "♦"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case clubs {
>simpleDescription = "clubs"
>color = .blackColor()
>symbol = "♣"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> }
> 
> let symbol = Suit.spades.symbol // "♠"
> ```
> 
> The proposed solution improves:
> - Readability as cases are closer with their related data;
> - Improves code maintainability as a case can be removed or added in one 
> place;
> - Improved performance as there is no need to recreate static values;
> - ~30% less lines of code in given example.
> 
> ## Detailed design
> 
>  Stored properties
> 
> Enum stored properties are supported the same way they are supported
> for structs can classes. Unlike enum associated values, stored
> properties are static to case and are shared for the same case.
> 
> Properties are accessed:
> ```swift
> let simpleDescription = Suit.spades.simpleDescription
> ```
> 
> Mutable properties can be set:
> ```swift
> Suit.spades.simpleDescription = "new simple description"
> ```
> 
>  Initialization
> 
> If enum 

Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Charles Srstka via swift-evolution
> On May 27, 2016, at 9:31 AM, plx via swift-evolution 
>  wrote:
> 
> For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
> convenience, but for more-complex type associated-type relationships it could 
> start to pay its own way.

Is it really that minor, though? For something so commonly encountered as 
methods that take sequences/collections, this:

func doSomething(foos: [Foo], bars: [Bar], bazzes: [Baz])

is not only a whole lot easier to type, but is worlds clearer to read than:

func doSomething(foos: S, bars: T, bazzes: U)

Not only is the latter line intimidating to look at as is, but it separates the 
contained type from the parameters themselves. Given how unwieldy this second 
form is, it seems almost certain that the former line will be used more 
frequently in the real world.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread Charles Srstka via swift-evolution
> On May 27, 2016, at 1:53 PM, Xiaodi Wu  wrote:
> 
> Firstly, the syntax is about to get a lot cleaner. Soon, your example will be:
> 
> func doSomething<
> S: Sequence, T: Sequence, U: Sequence
> >(foos: S, bars: T, bazzes: U)
> where S.Element == Foo, T.Element == Bar, U.Element == Baz

I wonder if it would be possible to introduce angle brackets on protocols to 
enumerate associated-type requirements? AFAIK, currently the angle brackets are 
not allowed at all, so it would be purely additive. Then, you could do 
something like:

func doSomething(foos: Sequence, bars: Sequence, bazzes: Sequence)

I don’t know about you, but that looks so much cleaner, for a function that 
doesn’t itself need to be generic.

(The generalized existentials solution is good, too. However, it requires 
making a separate typealias for every protocol you want to do this with, 
whereas the above idea wouldn’t.)

> Second, this syntax shows necessary complexity. Case in point: an array is a 
> Collection with randomly accessible elements, yet in your example you chose 
> SequenceType (aka Sequence). An instance of a type conforming to Sequence may 
> or may not have randomly accessible elements, it may or may not be consumed 
> after one pass, it may or may not have copy-on-write behavior, and it may or 
> may not be laid out contiguously in memory (which is not guaranteed for all 
> arrays but is for arrays with elements of primitive type)--and that's if it's 
> entirely held in memory at all.
> 
> By writing out the function declaration the way it's shown above, it's clear 
> what considerations that function will have to take into account. Assuming 
> that it can operate on arbitrary sequences just like it can an array is a 
> recipe for a lot of pain.

Yeah, I defaulted to Sequence just because I’ve been writing stuff lately that 
just iterates through a collection that’s passed in. If what the OP is 
proposing came to pass, it would need to map to Collection instead. Of course, 
sometimes all you need is a Sequence, so your point is well-taken. We do need 
*some* way to simplify this syntax, though.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Pitch: Small fix to where clauses in generics

2016-05-27 Thread Charles Srstka via swift-evolution
Forgive me if this has already been proposed in one of the generics threads; I 
did a quick check and didn’t see anything.

Currently, the code below does not compile:

protocol P {}

struct S: P {}

extension SequenceType where Generator.Element: P {
func foo() {}
}

func F(arr: [P]) {
arr.foo() // error: using 'P' as a concrete type conforming to protocol 
'P' is not supported
}

If one changes the where clause in the extension to say Generator.Element == P 
instead of : P, the above now works fine, but then the below does not:

protocol P {}

struct S: P {}

extension SequenceType where Generator.Element == P {
func foo() {}
}

func F(arr: [S]) {
arr.foo() // error: 'P' is not convertible to 'S'
}

It seems to me that the first example ought to work; if our constraint is that 
Generator.Element conforms to P, something typed as P itself should probably 
fit the requirement.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-26 Thread Charles Srstka via swift-evolution
> On May 26, 2016, at 4:47 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> - Abusing rawValue is just that: an abuse.

In addition, enums with associated types can’t have rawValues.

Why is this relevant, you may ask? Because error enums are a huge use case for 
something like this. Being able to do the below would be great:

enum MyError: ErrorProtocol {
accessor var localizedFailureReason: String
accessor var url: NSURL

case FileNotFound(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ?? “”)\” 
not found.”
self.url = url
}

case FileIsCorrupt(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ?? “”)\” 
is corrupt.”
self.url = url
}
}

This would be much cleaner than the existing method of using a switch to create 
a userInfo dictionary for creating an NSError to send to -[NSApplication 
presentError:] and similar methods.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Protected Access Level

2016-05-30 Thread Charles Srstka via swift-evolution
> On May 30, 2016, at 11:23 AM, Tino Heth <2...@gmx.de> wrote:
> 
>> Couldn’t you use the same reasoning to claim there shouldn’t be access 
>> control at all? Just add documention on methods you want to mark private 
>> telling users of the library not to call them!
> 
> I guess you are making fun, but actually, good old Objective-C messaging 
> works just that way:
> You can call all those dangerous and forbidden private methods easily...
> Writing special comments is just one way to document APIs; having no 
> (official) documentation at all is documentation as well ("don't use this!").
> 
> Most technical limitations can be cracked by skilled hackers (working around 
> "protected" is especially easy), so I really think that (for example) 
> declaring a method "final" says "I don't want this to be changed in a 
> subclass" in the first place, and the compiler error that is triggered when 
> you try to break the limitation is little more but a remainder.
> 
> Enforcing limitations using hacks causes confusion, so I would never use such 
> tricks in production code.

The purpose of access control isn’t really to keep out malicious users, though, 
it’s to prevent accidental misuse and clarify the interface.

One nice vector for accidental misuse is autocomplete. Even if layoutSubviews() 
has a great big // DON’T USE!!! in the documentation, it’s possible that 
someone is trying to remember the name of the API they need to use to tell the 
OS something needs to update its layout, so they type “layout” into the code 
editor, and lo and behold! Here’s something called layoutSubviews() that sounds 
like the sort of thing we want. And so it goes. A protected modifier in the 
language would prevent things like this.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Protected Access Level

2016-05-30 Thread Charles Srstka via swift-evolution
> On May 30, 2016, at 2:02 PM, Tino Heth <2...@gmx.de> wrote:
> 
>> The purpose of access control isn’t really to keep out malicious users, 
>> though, it’s to prevent accidental misuse and clarify the interface.
> mh, I would call this a "documenting intend" ;-)

If you get the method as an autocomplete, you won’t see the documentation 
telling you not to use it.

>> One nice vector for accidental misuse is autocomplete. Even if 
>> layoutSubviews() has a great big // DON’T USE!!! in the documentation, it’s 
>> possible that someone is trying to remember the name of the API they need to 
>> use to tell the OS something needs to update its layout, so they type 
>> “layout” into the code editor, and lo and behold! Here’s something called 
>> layoutSubviews() that sounds like the sort of thing we want. And so it goes. 
>> A protected modifier in the language would prevent things like this.
> true — but even subclasses shouldn't call layoutSubviews unregulated, so I 
> think this is a flawed example for the usefulness of protected.


This is why I prefer fileprivate(call) over protected.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Charles Srstka via swift-evolution
Forgive me if this has already come up, but since we’re talking about fixing 
generics, I wonder if there is any solution in the pipeline for this problem:

--

protocol P { func foo() }
struct S: P { func foo() { print("foo") } }

func doSomething(c: C) {
for each in c {
each.foo()
}
}

let arr: [P] = [S()]

doSomething(arr) // error: cannot invoke 'doSomething' with an argument list of 
type '([P])’

--

Why is this an error? The whole definition of [P] is basically an array of 
things that conform to P. Isn’t that exactly what “where Element: P” is asking 
for?

Changing Element: P to Element == P solves this particular issue, of course, 
but then passing something like [S] to the array will fail. The result is that 
you need to write two functions, and either have one eat the performance cost 
of constructing a new array that has the correct static type to pass to the 
other (since, unlike arrays, I can’t figure out a way to convert “Collection 
where Element: P” into “Collection where Element == P” with a simple cast), or 
just fill it with the dreaded copy-paste code. Neither seems ideal.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Charles Srstka via swift-evolution
> On May 29, 2016, at 5:16 PM, Austin Zheng  wrote:
> 
> I think the problem here is that P == P is true, but P : P is not (a protocol 
> does not conform to itself).

But if you have a variable, parameter, etc. typed as P, that’s *not* the 
protocol, since protocols aren’t concrete entities. What you have there, by 
definition, is something that conforms to P. Similarly, something like [P] is 
just a collection of things, perhaps of various types, which all have the 
common feature that they conform to P.

> I think there was some discussion about it on the original "Completing 
> Generics" thread from March. I'd probably ask on the swift-users list why P 
> can't be made to conform to P, and then put together a proposal if there's no 
> good reason.

Will do.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Charles Srstka via swift-evolution
> On May 29, 2016, at 9:20 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> On May 29, 2016, at 5:43 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>>> On May 29, 2016, at 5:16 PM, Austin Zheng <austinzh...@gmail.com 
>>> <mailto:austinzh...@gmail.com>> wrote:
>>> 
>>> I think the problem here is that P == P is true, but P : P is not (a 
>>> protocol does not conform to itself).
>> 
>> But if you have a variable, parameter, etc. typed as P, that’s *not* the 
>> protocol, since protocols aren’t concrete entities. What you have there, by 
>> definition, is something that conforms to P. Similarly, something like [P] 
>> is just a collection of things, perhaps of various types, which all have the 
>> common feature that they conform to P.
> 
> You have an existential value of type P.  It is a well known frustration in 
> Swift that the existential type corresponding to a protocol does not conform 
> to the protocol.  This has been discussed off and on at different times.  
> 
> There are a couple of reasons this is the case.  IIRC in some cases it 
> actually isn't possible for the existential to conform to the protocol in a 
> sound way.  And even when it is possible, I believe it has been said that it 
> is more difficult to implement than you might think.  Hopefully the situation 
> will improve in the future but I'm not aware of any specific plans at the 
> moment.

It’s been my understanding that a variable typed P in swift is equivalent to 
what we would have called id  in Objective-C—that is, an object of unknown 
type that conforms to P. Is this not the case? I am curious what the conceptual 
difference would be, as well as the rationale behind it.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Enhanced existential types proposal discussion

2016-05-29 Thread Charles Srstka via swift-evolution
> On May 29, 2016, at 10:13 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> On May 29, 2016, at 9:43 PM, Charles Srstka <cocoa...@charlessoft.com 
> <mailto:cocoa...@charlessoft.com>> wrote:
> 
>>> On May 29, 2016, at 9:20 PM, Matthew Johnson <matt...@anandabits.com 
>>> <mailto:matt...@anandabits.com>> wrote:
>>> 
>>> On May 29, 2016, at 5:43 PM, Charles Srstka via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>>> On May 29, 2016, at 5:16 PM, Austin Zheng <austinzh...@gmail.com 
>>>>> <mailto:austinzh...@gmail.com>> wrote:
>>>>> 
>>>>> I think the problem here is that P == P is true, but P : P is not (a 
>>>>> protocol does not conform to itself).
>>>> 
>>>> But if you have a variable, parameter, etc. typed as P, that’s *not* the 
>>>> protocol, since protocols aren’t concrete entities. What you have there, 
>>>> by definition, is something that conforms to P. Similarly, something like 
>>>> [P] is just a collection of things, perhaps of various types, which all 
>>>> have the common feature that they conform to P.
>>> 
>>> You have an existential value of type P.  It is a well known frustration in 
>>> Swift that the existential type corresponding to a protocol does not 
>>> conform to the protocol.  This has been discussed off and on at different 
>>> times.  
>>> 
>>> There are a couple of reasons this is the case.  IIRC in some cases it 
>>> actually isn't possible for the existential to conform to the protocol in a 
>>> sound way.  And even when it is possible, I believe it has been said that 
>>> it is more difficult to implement than you might think.  Hopefully the 
>>> situation will improve in the future but I'm not aware of any specific 
>>> plans at the moment.
>> 
>> It’s been my understanding that a variable typed P in swift is equivalent to 
>> what we would have called id  in Objective-C—that is, an object of 
>> unknown type that conforms to P. Is this not the case? I am curious what the 
>> conceptual difference would be, as well as the rationale behind it.
> 
> Existentials have their own type in Swift.  The problem you are running into 
> is because the generic constraint is looking at the existential type of P and 
> asking if that type conforms to P (which it does not - you can't write the 
> conformance and the compiler does not provide it for you).  It is not asking 
> if the type of the object underlying the existential value conforms to P 
> (which it necessarily does).  When you have a value of type P you have 
> already erased the type of the underlying object.

Have we not also erased the type of the underlying object with id , though? 
The only thing we get from the “id” is that it’s an Objective-C object of some 
type, which it would have to have been anyway in order to conform to the 
protocol in the first place. Thus the type of the object is erased, and the 
only thing we know about it is that it conforms to the protocol—just like 
something typed P in Swift.

What I’m trying to figure out is whether there’s any positive benefit or 
rationale to the reason things work the way they do here, or whether it’s just 
bugs / implementation details.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-06-22 Thread Charles Srstka via swift-evolution
> On Jun 22, 2016, at 1:28 AM, Douglas Gregor <dgre...@apple.com> wrote:
> 
> On Jun 20, 2016, at 11:03 AM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> It was deferred until after Swift 3.0.
>> 
>> https://github.com/apple/swift-evolution/pull/331 
>> <https://github.com/apple/swift-evolution/pull/331>
>> 
>> I plan to resubmit the proposal after Swift 3.0 comes out. Do you have any 
>> improvements or suggestions for it
> 
> The core team is reconsidering the deferral, because tackling this completely 
> is a fairly significant source-breaking change that we wouldn't want to do 
> post-Swift 3. That said, this is a tricky feature to get right, because it 
> involves dealing with intricacies of Swift's Objective-C interoperability as 
> well as the inner workings of NSError. I'll have some comments on your 
> proposal as well as my own thoughts on an implement approach in the next few 
> days. Hang in there :)

That is great news! This proposal seems like a good fit for Swift 3.0, to my 
mind, as it is very much along similar lines as the NSURL -> URL, NSDate -> 
Date, etc. conversions that are already being made.

I look forward to hearing your comments.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-06-20 Thread Charles Srstka via swift-evolution
It was deferred until after Swift 3.0.

https://github.com/apple/swift-evolution/pull/331 
<https://github.com/apple/swift-evolution/pull/331>

I plan to resubmit the proposal after Swift 3.0 comes out. Do you have any 
improvements or suggestions for it?

Charles

> On Jun 20, 2016, at 12:51 PM, Shawn Erickson <shaw...@gmail.com> wrote:
> 
> I am curious on the disposition of this discussion / proposal pitch. Has any 
> additional effort taken place since this email thread tampered off?
> 
> On Sat, May 14, 2016 at 2:40 AM Charles Srstka via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> On May 14, 2016, at 3:51 AM, Michael Peternell <michael.petern...@gmx.at 
>> <mailto:michael.petern...@gmx.at>> wrote:
> 
>> 
>> For interoperability, ErrorType and NSError should be toll-free-bridged, 
>> like CFStringRef and NSString. Converting between them should be a no-op at 
>> runtime.
> 
> That would be technically infeasible without restricting ErrorType to 
> reference types using the Objective-C runtime, which I don’t think anyone 
> wants to do.
> 
>> I prefer runtime/ABI consistency over syntax/language consistency. 
>> MyErrorType2 should be represented as an NSError with domain 
>> @"MyErrorType2", whatever code is defined in that error type, and if you 
>> want userInfo you have to create the beast as an NSError object in the first 
>> place. I think userInfo is not visible in the Swift-enum-representation. If 
>> you want to have a Swift Error representation that includes userInfo, you'd 
>> have to either change the architecture or introduce special support on the 
>> language level (e.g. a magic `er.userInfo` of type 
>> `Dictionary<String,AnyObject>` for every `er: ErrorType` and a 
>> `er.withUserInfo(userInfo)` to add a userInfo dictionary to an error type: 
>> e.g. 
>> `MyErrorType2.fooConditionFound.withUserInfo([NSLocalizedDescriptionKey: 
>> "that was really bad"])` and maybe even a convenience method as a protocol 
>> extension like 
>> `MyErrorType.fooConditionFound.withLocalizedDescription(localizedString: 
>> "ReallyBad")`.
> 
> Adding a userInfo property to the protocol declaration (with a default 
> implementation for those that don’t want to implement it) would solve this 
> without any low-level hacking.
> 
>> And the key of a dictionary should really always be a String, not just an 
>> NSObject.)
> 
> I actually agree; I used [NSObject : AnyObject] since that’s what NSError’s 
> userInfo is currently defined as. Putting [String : AnyObject] in the 
> protocol instead would be fine, although you’d have to do a little sanity 
> checking in the bridging to filter out non-string keys from the dictionary.
> 
>> (I know if you have something like `case SpecialError(Int)` in your 
>> ErrorType declaration, the above method does not work; you'd have to create 
>> an NSError-subclass for it. Or maybe not? Just add a "SpecialError_arg0" key 
>> to userInfo, value can be an NSNumber? There are more edge cases here but 
>> they are all solvable.)
>> 
>> On the other hand, I don't think that enumerations in general should support 
>> instance variables. One of the nice things for an enum is that I as a 
>> programmer can always be sure that it *is* just an enum, and nothing else. 
>> Adding iVars to enums would effectively turning enums to structs, and each 
>> time I see a switch statement I'll have to think "is this really all? or is 
>> there some stealth value attached to this enum? is every .MadeAMistake 
>> object always the same?" Keeping the inconsistency constrained to the 
>> ErrorType is much nicer than turning every enum into a struct.
> 
> Adding instance variables to enums is not necessary for this. The userInfo 
> here can be implemented as a computed property, as it would be in enums (in 
> classes and structs, of course, it would be up to the developer whether to 
> make it a stored or computed property).
> 
>> There will always be rough edges when converting between two languages, 
>> that's unavoidable. Try to translate a text that contains a lot of the words 
>> "safety" and "security" into German. Good luck, they both translate to the 
>> same word. And so there also cannot be a perfectly consistent translation 
>> between ErrorType and NSError. If you want to achieve a good translation, 
>> you'd have to change the ErrorType to something different. E.g. a special 
>> language construct `def-error MyErrorType { case MadeAMistake; case 
>> RanOutOfCake }` - ma

Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Charles Srstka via swift-evolution
> On Jun 15, 2016, at 10:46 PM, Robert Widmann  wrote:
> 
> That is a different discussion entirely.  Once you fall below internal then 
> we do not default to internal, we default to the maximum access level of the 
> outer decl.  Read that linked part of the type checker if you don't believe 
> me.  I also had to fix several hundred lines of SwiftPM and corelibs code 
> that was failing to build because of this exact access control schema in 
> apple/swift#3000.  You'll notice I effectively changed two lines in Sema and 
> this was the fallout.  I did nothing special to change our existing access 
> control mechanism, it's just how it has always worked.  Try declaring this 
> explicitly and see the diagnostic we emit, then it'll be easier to see why 
> this is a problem:
> 
> private struct X {
>internal var x : String = "" // expected-warning
> }
> 
> ~Robert Widmann

The statement was that "They do not default to ‘internal' when unannotated, 
they default to the highest possible access level they can get given the decl 
they're in.” This is demonstrably untrue, since if the type they’re in is 
public, the highest possible access level they could get would be public, and 
unannotated properties in a public type are *not* public. They are internal.

> On Jun 15, 2016, at 10:49 PM, Robert Widmann  wrote:
> 
> Also consider what would happen if we did allow access control to escalate 
> here: Suppose that code did not emit a diagnostic, then the member is still 
> private because you cannot reference the class outside of file scope.

Which is… exactly what we want.

> You see, even if we did escalate access control for unannotated members, even 
> if we did that (which we don't) you wouldn't even be able to reap the 
> benefits.  It makes no sense.


A good way to think of it is in terms of what permissions are *removed* by the 
access modifiers, rather than *added*. Then, everything makes perfect sense:

Public removes nothing.
Internal removes access outside a module.
Fileprivate removes access outside a file.
Private removes access outside a declaration.

If you have an internal property within a public type, the “public” modifier 
removes nothing, and the “internal” modifier then removes access from outside 
that module. The result is access from only within the module.

If you have an internal property within an internal type, the “internal” 
modifier on the type removes access from outside the module, and then the 
“internal” modifier on the property would remove access from outside the 
module, except that such access is already removed. Result is access from only 
within the module.

With an internal property inside a private type within another type, the 
“private” modifier on the type removes access from outside its parent type, and 
the “internal” modifier removes access from outside the module—but since no 
entities outside the type’s parent type currently have access, and since the 
parent type is in the current module anyway, this once again has no effect. 
Result is that the property is only accessible from inside its parent type.

With an internal property inside a private type that’s at the top of the file’s 
scope, the “private” modifier on the type removes access from outside the file, 
and the “internal” modifier removes access from outside the module—but since no 
entities outside the file currently have access, and since the file is in the 
current module, this once again has no effect. Result is that the property is 
only accessible from inside the current file.

And etc.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Charles Srstka via swift-evolution
> On Jun 15, 2016, at 11:04 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Result is that the property is only accessible from inside its parent type.

*inside the type’s parent type

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-16 Thread Charles Srstka via swift-evolution
> On Jun 15, 2016, at 11:16 PM, Robert Widmann  wrote:
> 
> Charles we've diverged from the actual issue at hand to nitpick my English.  
> Read the code (that std::min tho!).  We have a problem here and no obvious 
> solution that doesn't involve special-casing parts of this proposal.  Do you 
> have a solution or shall we take this offline?  I can provide you my iMessage 
> information in a person email if you wish to discuss this with me or any 
> other members of the team, but the list is not the most productive place for 
> this.
> 
> Thanks,
> 
> ~Robert Widmann

I am not sure why you think I am nitpicking your English (unless if you are 
possibly referring to the post where I corrected my own typo, but that was my 
English, not yours). What I am trying to express is that I do not believe there 
is an issue with the syntax as proposed. If there is no access modifier on a 
declaration, there is no reason that that declaration should be less visible 
than its container, except in the case that the container’s visibility is 
greater than the default level of internal—i.e. it is public.

Furthermore, I do not see the need for an access modifier that says to give 
something the same visibility as its parent, since for all access levels other 
than public (and of course, for public APIs, you want to declare those 
explicitly anyway), you get that already by default, so an access modifier 
seems somewhat redundant.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Charles Srstka via swift-evolution
> On Jun 15, 2016, at 8:36 PM, Robert Widmann  wrote:
> 
> Point 3 is *not* how member lookup applies access control levels to 
> unannotated properties of outer structures (see 
> https://github.com/CodaFi/swift/blob/fb9f9536a5760369457d0f9c49599415cbc36e07/lib/Sema/TypeCheckDecl.cpp#L1470
>  
> )
>  and makes no sense.  They do not default to "internal" when unannotated, 
> they default to the highest possible access level they can get given the decl 
> they're in.  A private structure will necessarily have private members.  This 
> is the whole point of me raising this issue.  If we were to break containment 
> we would break the very motivation for this proposal.  And if we wish to do 
> this to get this feature right, then the proposal needs to be amended to 
> include that kind of caveat.

This isn’t correct. If the outer type is marked “public”, and its properties 
are not annotated, those properties will be internal, *not* public, and you 
will not be able to see them outside of the module.

The rule can basically be summed up as “internal by default, unless we can’t 
because our enclosing type is more restrictive than internal. Then, be as 
visible as the enclosing type is."

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] A Problem With SE-0025?

2016-06-15 Thread Charles Srstka via swift-evolution
I think you guys are making this more complicated than it is. The rules here 
seem fairly simple:

1. The default access level is “internal”.

2. A type declared “private” at the top level will be visible to the file only.

3. If they are not given an access level, properties declared on the type will 
get the default “internal” access level, but since their containing type is not 
visible outside the file, they will not be visible either.

Thus any properties on the type will effectively inherit the access level of 
that type, unless the type’s access level is broader than “internal”. For the 
example of a private type at the top level of a file, its properties will 
effectively be fileprivate.

Charles

> On Jun 15, 2016, at 5:48 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Jun 15, 2016, at 5:17 PM, Robert Widmann  > wrote:
> 
>> I await their opinions, but even with that change we still have a problem 
>> with the philosophy here.  The motivation behind the fileprivate/private 
>> distinction is, as you say in the proposal "[a] reliable way to hide 
>> implementation details...".  Why would you want any members you're trying to 
>> hide to be visible in any scope other than the one you create with the decl 
>> (which is, without a doubt, also a lexical scope)?  It is analogous with 
>> other access control levels: a public outer decl implies public inner 
>> members just as a fileprivate one implies fileprivate inner members.  Is it 
>> not antithetical to being able to hide things if they remain visible despite 
>> the outer decl declaring itself supposedly being sealed?  In your examples, 
>> you declare private members that you do not wish to leak into top level 
>> scope because they are, after all, supposedly hidden.  Should the same 
>> semantics you have given not also apply to private decls no matter where 
>> they lie? 
>> 
> 
> Sorry, missed the example in my last reply.
> 
>> Should this compile:
>> 
>> private struct Outer {
>> let inner = Inner()
>> }
>> 
>> Outer().inner
> 
> Aside from the fact that you can't write a standalone statement at the top 
> level of a file and it isn't clear what 'Inner' is, yes.  This would be valid:
> 
> private struct Outer {
> struct Inner {}
> let inner = Inner()
> }
> 
> private let inner = Outer().inner
> 
> Note that the top level 'inner' must be 'private' or 'fileprivate' because 
> 'Inner' is not visible outside the file.
> 
>> 
>> If this shouldn't:
>> 
>> struct Outer {
>> private let inner = Inner()
>> }
>> 
>> extension Outer {
>> var inner2 : Inner { return self.inner }
>> }
> 
> The extension introduces a new scope so this is not valid.
> 
>> 
>> Visibility being a function of scope, lexical or otherwise, seems too coarse 
>> a metric for access control in general without further clarification of what 
>> the definition of "hidden" is.
> 
> The lexical scope of the declaration itself (not a scope introduced by the 
> declaration) is perfectly clear.  You may not like it or agree that it is 
> desirable but it certainly isn't ambiguous.
> 
>> 
>> ~Robert Widmann
>> 
>> 2016/06/15 12:38、Matthew Johnson > > のメッセージ:
>> 
>>> 
 On Jun 15, 2016, at 2:29 PM, Robert Widmann > wrote:
 
 The meaning of private according to the proposal is not scope-dependent, 
 it is decl-dependent.  The mental gymnastics we are both going through 
 right now are not in the proposal.  I would like them to be.
>>> 
>>> I agree that the proposal is too sparse on the details and that is the 
>>> source of the confusion.  
>>> 
>>> Ilya wanted me to write this proposal and only did it himself because I 
>>> didn’t have time to do it as quickly as he wanted.  I know what the 
>>> original intent of the proposal was (I can’t speak for the core team on 
>>> their mental model of it when they accepted it).
>>> 
>>> That said, the title of the proposal is “scoped access level” and the 
>>> detailed design says "visible only within that lexical scope”.  And the 
>>> entire discussion was always about lexical scope.  I believe the reason the 
>>> “proposed solution” section says “current declaration” is because *most* 
>>> lexical scopes are introduced by a declaration.  That is sloppy language 
>>> that should have been cleaned up prior to review.
>>> 
>>> I appreciate you working on implementing this.  I also understand if you 
>>> want to hold off until the core team can chime in on the semantics they 
>>> intend.  
>>> 
>>> Matthew
>>> 
 
 ~Robert Widmann
 
 2016/06/15 12:26、Matthew Johnson > のメッセージ:
 
> 
>> On Jun 15, 2016, at 2:19 PM, Robert Widmann > 

Re: [swift-evolution] [Proposal draft] NSError bridging

2016-06-27 Thread Charles Srstka via swift-evolution
Obviously, I’m in favor of this one. +1!

I think I did prefer the older name of CustomUserInfoError for the 
domain/code/userInfo protocol, rather than CustomNSError. This is just because 
I’d like to be able to do a global search through my project for “NSError” and 
have it turn up empty. Maybe a silly reason, I know. ;-)

I sent a few more comments off-list before I realized you’d posted the proposal 
already, so you can peruse, consider, and/or discard those at your leisure. 
It’s nothing terribly important, though; this proposal is pretty great as is.

Thanks so much for doing this! I’m really excited for better error handling in 
Swift 3.

Charles

> On Jun 27, 2016, at 1:17 PM, Douglas Gregor  wrote:
> 
> Hi all,
> 
> Proposal link: 
> https://github.com/DougGregor/swift-evolution/blob/nserror-bridging/proposals/-nserror-bridging.md
> 
> Here is a detailed proposal draft for bridging NSError to ErrorProtocol. 
> Getting this right is surprisingly involved, so the detailed design on this 
> proposal is fairly large. Comments welcome!
> 
>   - Doug
> 
> NSError Bridging
> 
>   • Proposal: SE-
>   • Author: Doug Gregor, Charles Srstka
>   • Status: Awaiting review
>   • Review manager: TBD
> Introduction
> 
> Swift's error handling model interoperates directly with Cocoa's NSError 
> conventions. For example, an Objective-C method with an NSError** parameter, 
> e.g.,
> 
> - (nullable NSURL *)replaceItemAtURL:(NSURL *)url 
> options:(NSFileVersionReplacingOptions)options error:(NSError **)error;
> will be imported as a throwing method:
> 
> func replaceItem(at url: URL, options: ReplacingOptions = []) throws -> URL
> Swift bridges between ErrorProtocol-conforming types and NSError so, for 
> example, a Swift enum that conforms toErrorProtocol can be thrown and will be 
> reflected as an NSError with a suitable domain and code. Moreover, an 
> NSErrorproduced with that domain and code can be caught as the Swift enum 
> type, providing round-tripping so that Swift can deal in ErrorProtocol values 
> while Objective-C deals in NSError objects.
> 
> However, the interoperability is incomplete in a number of ways, which 
> results in Swift programs having to walk a careful line between the 
> ErrorProtocol-based Swift way and the NSError-based way. This proposal 
> attempts to bridge those gaps.
> 
> Swift-evolution thread: Charles Srstka's pitch for Consistent bridging for 
> NSErrors at the language boundary, which discussed Charles' original proposal 
> that addressed these issues by providing NSError to ErrorProtocol bridging 
> and exposing the domain, code, and user-info dictionary for all errors. This 
> proposal expands upon that work, but without directly exposing the domain, 
> code, and user-info.
> 
> Motivation
> 
> There are a number of weaknesses in Swift's interoperability with Cocoa's 
> error model, including:
> 
>   • There is no good way to provide important error information when 
> throwing an error from Swift. For example, let's consider a simple 
> application-defined error in Swift:
> 
> enum HomeworkError : Int
> , ErrorProtocol {
>   
> case
>  forgotten
>   
> case
>  lost
>   
> case
>  dogAteIt
> }
> 
> One can throw HomeworkError.dogAteIt and it can be interpreted as an NSError 
> by Objective-C with an appropriate error domain (effectively, the mangled 
> name of the HomeworkError type) and code (effectively, the case 
> discriminator). However, one cannot provide a localized description, help 
> anchor, recovery attempter, or any other information commonly placed into the 
> userInfo dictionary of an NSError. To provide these values, one must 
> specifically construct an NSError in Swift, e.g.,
> 
> throw NSError(code: HomeworkError.dogAteIt.rawValue
> ,
>   domain: HomeworkError
> .
> _domain,
>   userInfo: [ NSLocalizedDescriptionKey 
> : "the dog ate it" ])
>   • There is no good way to get information typically associated with 
> NSError's userInfo in Swift. For example, the Swift-natural way to catch a 
> specific error in the AVError error domain doesn't give one access to the 
> userInfo dictionary, e.g.,:
> 
> catch let error as AVError where error == .
> diskFull {
>   
> // AVError is an enum, so one only gets the equivalent of the code.
> 
>   
> // There is no way to access the localized description (for example) or
> 
>   
> // any other information typically stored in the ``userInfo`` dictionary.
> 
> }
> 
> The workaround is to catch as an NSError, which is quite a bit more ugly:
> 
> catch let error as NSError where error._domain == AVFoundationErrorDomain && 
> error._code == AVFoundationErrorDomain.diskFull.rawValue
>  {
>   
> // okay: userInfo is finally accessible, but still weakly typed
> 
> }
> 
> This makes it extremely hard to access common information, such as the 
> localized description. Moreover, the userInfo dictionary is effectively 
> untyped so, for example, one 

Re: [swift-evolution] An upcoming proposal for simplifying leak free, safe closures.

2016-06-26 Thread Charles Srstka via swift-evolution
I like it. Accidental capture of a variable is probably one of the primary 
causes of retain cycles in modern Swift code. Requiring the capture to be 
explicit would take a lot of the surprise out of it and force the developer to 
think about the capture semantics.

+1.

Charles

> On Jun 26, 2016, at 2:10 PM, Christopher Kornher via swift-evolution 
>  wrote:
> 
> I may be too late for Swift 3, but I am planning to propose changes to the 
> default behavior for closures capturing object references. The introduction 
> of Swift Playgrounds has raised the importance of simplifying the coding of 
> leak-free, crash-free closures. New developers should not have to understand 
> closure memory management to start writing useful and correct code.
> 
> The topic of the closure weak/strong dance has been discussed on this list 
> before. This proposal differs from previous proposals in that it will 
> eliminate the dance altogether by default. I am very interested in hearing 
> others’ opinions as to whether the benefits outweigh the costs of various 
> options.
> 
> I have found that Swift’s capture lists and rules are a bit of a mystery to 
> many experienced developers, even though Swift’s closure capture rules are 
> very similar to those of Objective-C. Capture lists are probably thought of 
> as opaque incantations by many new Swift developers if they are aware of them 
> at all. Capture lists should, ideally, not be needed for sensible and safe 
> default behavior.
> 
> This discussion is iOS / OS X centric and uses terms from those domains, but 
> these issues should be applicable to almost any codebase that uses closures 
> capturing object references.
> 
> Capture lists are required by the fact that object references are captured as 
> `strong` by default, often leading to strong reference cycles and memory 
> leaks.
> 
> Use of ‘unowned’ 
> 
> Many examples of using closures capture self as `unowned`. Often, this 
> pattern does not scale well beyond simple examples. iOS and MacOS 
> applications with dynamic UIs, for example, switch between numerous views and 
> view controllers. These objects are dereferenced and reclaimed when they are 
> no longer needed. Closures capturing these objects as `unowned` crash when 
> the references are accessed.
> 
> Unfortunately, ‘unowned’ captures are tempting because they eliminate `guard` 
> and `if let` constructs and avoid littering code with optional unwrapping. 
> They are also slightly more performant, but this difference is probably 
> negligible in most application code.
> 
> Capturing escaping object references as `unowned` is only safe when object 
> lifetimes are perfectly understood. In complex systems, it is difficult to 
> predict execution order. Even if object lifetimes are perfectly understood 
> when code is originally written, seemingly innocuous changes to complex 
> systems can negate original assumptions.
> 
> For these reasons, I believe that capturing object references as `unowned` 
> should be considered an advanced optimization technique.
> 
> I now routinely create closures that capture `self` and other object 
> references as ‘weak’ even if I think that I feel that `unowned ` would be 
> safe. This may not be the absolutely most performant solution, but it is 
> straightforward and robust.
> 
> 
> The core proposal:
> ——
> 
> Closures capturing object references should automatically capture all object 
> references as weak.
> 
> The closure defined in:
> 
> ```
> class ClosureOwner2 {
> var aClosure: (() -> Void)?
> 
> func aMethod() {
> aClosure = { [weak self] in
>self?.someOtherMethod()
>}
> }
> 
> func someOtherMethod(){}
> }
> ```
> 
> would normally be written as: 
> 
> ```
> aClosure = {
>self?.someOtherMethod()
> }
> ```
> Closures that can be optimized to safely capture object references as 
> `unowned` can use the current syntax.
> 
> Swift 2 closure without explicit capture lists for object references will not 
> compile.
> 
> Capturing strong object references can be very useful in certain 
> circumstances and have a straightforward syntax:
> 
> ```
> aClosure = { [strong self] in
>self.someOtherMethod()
> }
> ```
> 
> 
> Alternatives / Modifications / Improvements(?):
> —
> 
> 1) Closures with object references could be simplified further by implicitly 
> including ‘let’ guards for all object references: 
>  
> aClosure = {
>// This is included implicitly at the top of the closure:
>   // guard let strongSelf = self else { return }
> 
> /*strongSelf*/ self.someOtherMethod()
>   print( “This will not appear when self is nil.” )
> 
>   … other uses of strongSelf…
> 
> }
> 
> This would have the effect of making the execution of the closure dependent 
> upon the successful unwrapping of all of its object 

Re: [swift-evolution] Prohibit invisible characters in identifier names

2016-06-24 Thread Charles Srstka via swift-evolution
> On Jun 24, 2016, at 8:27 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> (Personally I really don't understand why we need anything than ASCII codes 
> for identifiers. This could solve all the problems with invisible 
> space/left-to-right-flags/complicated rules/graphemes etc. But someone needs 
> to be able to put dog emoji as identifiers.. well.. OK)

Did you even watch the WWDC keynote? This was basically the transcript of it:

"Emoji! Emoji emoji emoji. Emoji emoji. Emoji! Emoji emoji emoji emoji. Emoji 
Emoji? Emoji. Emoji!”

(cue a bunch of emoji bouncing around on an iPad screen)

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Idea] Find alternatives to `switch self`

2016-04-08 Thread Charles Srstka via swift-evolution
> On Mar 23, 2016, at 5:13 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> * Allow you to attach member definitions to particular cases. It would be an 
> error if they didn't all define the same members, unless there was a 
> top-level catchall.
> 
>enum Suit: Int {
>var isRed: Bool { return false }
> 
>case Hearts {
>let description: String { return "♥️" }
>let isRed: Bool { return true }
>}
>case Spades {
>let description: String { return  "♠️" }
>}
>case Diamonds {
>let description: String { return  "♦️" }
>let isRed: Bool { return true }
>}
>case Clubs {
>let description: String { return  "♣️" }
>}
> 
>static var all = [ Hearts, Spades, Diamonds, Clubs ]
>}

Oh my, I absolutely *love this.* This would be a godsend for making ErrorType 
enums that bridge nicely to NSErrors, with code and userInfo properties 
attached to each case.

+1.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Idea] How to eliminate 'optional' protocol requirements

2016-04-11 Thread Charles Srstka via swift-evolution
> On Apr 11, 2016, at 12:03 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> on Sun Apr 10 2016, Dietmar Planitzer  > wrote:
> 
>>> On Apr 10, 2016, at 11:46, Dave Abrahams via swift-evolution
>>  wrote:
>>> 
>>> 
>>> on Sun Apr 10 2016, Dietmar Planitzer 
>> wrote:
>>> 
 I’m not sure whether you’ve read the conclusion of my mail since
 you’ve only commented on the introductory part. In the conclusion I
 wrote that a possible approach for the replacement of ObjC-style
 optional protocol methods would be:
 
 1) the default implementation of a protocol method must be defined
>> in
 the protocol (so just like in native Swift protocols today).
>>> 
>>> ? They can and must be defined in protocol extensions today.
>> 
>> I know.
>> 
 
 2) we add a way for a protocol provider to check whether the
>> protocol
 adopter has provided an “override” of the default method.
>>> 
>>> I object to this part.
>> 
>> You object why? I do understand why you object to the ObjC model since
>> there is not necessarily an implementation of the protocol method and
>> thus the protocol provider has to guard every call with an existence
>> check. But in this model here we would be guaranteed that there would
>> be an implementation of the protocol method and thus guarding the call
>> wouldn’t be necessary.
> 
> Because it's a needless complication that will encourage protocol and
> algorithm designers to create inefficient programs because they know the
> user can fall back on this hack.  Nobody thinks that classes need the
> ability to check whether a given method is overridden.  Why should this
> be needed for protocols?


Actually, Apple’s frameworks have often contained code to check whether given 
methods are overridden, and this has allowed them to deprecate override points 
and replace them with better API without breaking source or binary 
compatibility. The most obvious example that comes to mind is NSDocument; when 
they introduced the newer override points such as -readFromURL:ofType:error: 
that used NSURLs instead of paths and allowed returning an NSError, they added 
code in the default implementation to check whether the subclass overrode the 
older -readFromFile:ofType: method and if it did, called that method. 
Otherwise, it would call the modern methods. This way, older applications that 
were still overriding -readFromFile:ofType: would continue to work correctly.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Draft] Abolish IUO type

2016-03-19 Thread Charles Srstka via swift-evolution
If you know something’s non-null, is there any advantage to keeping it in an 
implicitly-unwrapped optional instead of a normal non-optional type?

Charles

> On Mar 17, 2016, at 11:08 PM, Step C via swift-evolution 
>  wrote:
> 
> That just forces the unwrap to the base type, it doesn't turn it into an 
> autounwrapped (or IUO). 
> 
> On Mar 17, 2016, at 10:26 PM, Jed Lewison via swift-evolution 
> > wrote:
> 
>> 
>>> On Mar 17, 2016, at 8:50 PM, Brent Royal-Gordon via swift-evolution 
>>> > wrote:
>>> 
>>> @autounwrapped let foo = functionReturningOptional()
>>> 
>>> I *believe* that, without the `@autounwrapped` attribute, there's no way to 
>>> go from T? to T! without actually restating T somewhere.
>> 
>> 
>> I think you could express this as:
>> 
>>  let foo = functionReturningOptional()!
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting 0004 etc. - Swift deprecations

2016-04-02 Thread Charles Srstka via swift-evolution
While this style works, and definitely can substitute for a classical for loop, 
it is not quite as nice, because it cannot limit i’s scope to the loop. The 
variable will be visible outside of the loop body.

Charles

> On Apr 2, 2016, at 8:43 PM, Andrew Bennett via swift-evolution 
>  wrote:
> 
> On that note here is a convenient pattern I've used in the rare cases I 
> haven't been able to convert to a "for in" syntax when refactoring:
> 
> var i = 0
> while i < 10 {
> defer { i += 1 }
> print(i)
> }
> 
> To be honest I don't really mind this syntax, I often found during 
> refactoring:
>  * the c-style "for" was broken up over multiple lines anyway
>  * I wanted the last value of `i` outside the loop, so it was written "for ; 
> check; incr"
>  * It still works with continue, although it does increment "i" on break
> 
> 
> On Sun, Apr 3, 2016 at 11:19 AM, Ross O'Brien via swift-evolution 
> > wrote:
> Because you're coming to the discussion late, the arguments you're making are 
> a little out of date. It's no longer a case of not removing these features. 
> It's now a case of having a compelling reason to put them back.
> 
> I trust you've read the proposals that were put forward. For the benefit of 
> those reading, they're here:
> https://github.com/apple/swift-evolution/blob/master/proposals/0004-remove-pre-post-inc-decrement.md
>  
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0007-remove-c-style-for-loops.md
>  
> 
> 
> There are several disadvantages listed for keeping these two features. Those 
> are the arguments you need to counter. As it happens, both proposals refer to 
> the metric of 'if this wasn't already in Swift, would it be accepted for 
> Swift 3?' and both features have been deemed to fail this criterion. That's 
> what you need to address.
> 
> Bear in mind these decisions were made several months ago, and both features 
> have already been deprecated as of Swift 2.2, which is now in use in 
> production code, many developers (including myself) are already refactoring 
> their code to remove uses of these syntax forms.
> 
> 
> On Sun, Apr 3, 2016 at 12:45 AM, John Heerema via swift-evolution 
> > wrote:
> Warning - long post.
> I know that some folks really hate long posts, so let me apologize right
> now for this being a long post. Please feel free to skip right on past it.
> I posted it on a weekend, when there¹s less mailing list traffic, but that
> doesn¹t make it any shorter.
> 
> Warning - revisits two approved deprecations.
> If you really, really hate it when people want to revisit decisions that
> have already been made, please just skip right past this post. My
> apologies for not contributing to the discussion when these decisions were
> originally being made!
> 
> The day that Swift was announced at the WWDC was very
> exciting for me, and I immediately read the Swift book from beginning to
> end.
> Swift quickly became my favourite language: I felt that the Swift language
> developers had created a beautiful language that combined expressiveness
> with
> practicality in a way that made Swift code both powerful and easy to
> understand. Swift was crafted by some very smart and practical people.
> 
> To put my thoughts into perspective, I should mention that
> I¹ve taught Computer Science at a senior University level for years, and
> have
> worked in industry for decades. As a computer scientist, I¹ve had a strong
> interest in computer languages for many years. I became an Apple developer
> upon
> purchasing an Apple Lisa a very long time ago.
> 
> Over the past couple of years though, I¹ve seen what I think
> of as a growing emphasis on strict feature orthagonality at the expense of
> practicality in Swift. Perhaps this because much of the feedback on the
> language has been provided by those of us who are interested in computer
> languages. But for whatever reasons, the Swift language seems to have
> become
> more cluttered and less friendly.
> 
> As I¹ve gone through the various beta releases, I¹ve seen
> changes that detract from the experience of using Swift, for reasons that
> seem
> related to ³language purity².
> 
> I was finally moved to try to express my thoughts after
> seeing a couple of what I think of as particularly inadvisable proposals
> for
> Swift version 3 and beyond.
> 
> Unary increment and decrement operators: ++ and ‹
> 
> The first of these was the now approved removal of Swift¹s
> convenient unary increment and decrement operators. I would agree with
> some of
> the comments that have been made about these operators not being quite
> orthogonal with other expressive 

Re: [swift-evolution] Revisiting 0004, 0007 etc. - Swift deprecations

2016-04-03 Thread Charles Srstka via swift-evolution
> On Apr 3, 2016, at 8:51 PM, David Waite via swift-evolution 
>  wrote:
> 
> Swift also has the benefit of built-in access to C/C++ and in some 
> environments Objective-C code and libraries. This means it does not have to 
> strive to either replace or to have universal coverage of features in these 
> languages. 
> 
> For example, I cite pointers in Swift: while UnsafePointer exists, one would 
> be hard-pressed to choose to use it for code involving significant pointer 
> manipulation over the equivalent C code - the C code is much more terse, and 
> in the domain of unsafe pointer juggling the C that terseness actually can 
> make the code more understandable. We have the benefit of letting C be good 
> at what C was made for, and having that C code talk to Swift. The language 
> doesn't need “Pure Swift” in the way a cross-platform distribution language 
> like Java needs “Pure Java”.

Keep in mind that this is only (fully) true on Apple platforms; it’s my 
understanding that the open-source version of Swift does not include the 
Objective-C bridge, with its bridging headers and all that jazz. Therefore, 
interop with C code is probably limited to calling things from libraries.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pre-proposal] Automatic unwrapper boolean properties using unless keyword

2016-03-31 Thread Charles Srstka via swift-evolution
What I often do is use ?? to provide a default (usually false).

if myList?.isEmpty ?? false {
print(“Empty”)
} else {
print(“Not empty”)
}

The other thing you can do, of course, is to use a ‘where’ statement:

if let list = myList where list.isEmpty {
print(“Empty”)
} else {
print(“Not empty”)
}

Charles

> On Mar 31, 2016, at 4:54 PM, Guilherme Torres Castro via swift-evolution 
>  wrote:
> 
> Hello,
> 
> This is a Idea I got from Objetive-C, where nil is evaluate no false, this 
> feature can keep the code clean. For example:
> 
> if (![myList isEmpty]) { ... }
> Will evaluate true or false even if myList is nil.
> I know that Swift is not Design to work like Objetive-C, but sometimes this 
> make the code cleaner.  
> 
> Example:
> if !myList?.isEmpty { print("Ok") }
> This is much more cleaner and easy to read than:
> 
> if !(myList != nill && mylist!.isEmpty) { print("Ok") }
> Moreover the tip from the Xcode (when you type the  lead user to generate 
> wrong code when you type this code :
> 
> if !((myList?.isEmpty)) != nil { print("Ok") }
> As you can see the suggestion made by the Xcode will not work, because event 
> if the list is empty the expression will return true.
> 
> My ideia is to use some special syntax that permit optional to be evaluate to 
> boolean expression. Those syntax may be like in ruby 
> . 
> 
> 
> code if condition
> So the code from the example will be:
> 
> print ("Ok") if !myList?.isEmpty
> Or using the unless keyword:
> 
> unless myList?.isEmpty print("not empty") else print "empty"
> 
> I didn't spent much time thinking about the syntax keyword, because I want to 
> know first if you will consider a great addition to the language, if so, we 
> can work on details and a formal proposal.
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pre-proposal] Automatic unwrapper boolean properties using unless keyword

2016-03-31 Thread Charles Srstka via swift-evolution
> On Mar 31, 2016, at 5:04 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> What I often do is use ?? to provide a default (usually false).
> 
> if myList?.isEmpty ?? false {
> print(“Empty”)
> } else {
> print(“Not empty”)
> }

That’s what I get for writing a reply quickly; in this particular case the 
default should probably be true, since you probably want to treat a nil list as 
empty.

if myList?.isEmpty ?? true {
print(“Empty”)
} else {
print(“Not empty”)
}

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0036: Requiring Leading Dot Prefixes for Enum Instance Member Implementations

2016-04-02 Thread Charles Srstka via swift-evolution
The correctness of this proposal seems somewhat self-evident.

+1.

Charles

> On Mar 31, 2016, at 10:41 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0036 "Requiring Leading Dot Prefixes for Enum Instance 
> Member Implementations" begins now and runs throughApril 5, 2016. The 
> proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md
>  
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> Proposal link:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md
>  
> 
> Reply text
> 
> Other replies
>  What 
> goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
> What is your evaluation of the proposal?
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> Does this proposal fit well with the feel and direction of Swift?
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> More information about the Swift evolution process is available at
> 
> https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> Thank you,
> 
> Doug Gregor
> 
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Mutability for Foundation types in Swift

2016-04-22 Thread Charles Srstka via swift-evolution
One comment:

"In the most common case where a developer does not provide a custom reference 
type, then the backing store is our existing NSData and NSMutableData 
implementations. This consolidates logic into one place and provides cheap 
bridging in many cases (see Bridging for more information).”

Would it not be more efficient to bridge to the C-based CFData and 
CFMutableData implementations instead, to avoid the object overhead?

Charles

> On Apr 22, 2016, at 12:18 PM, Tony Parker via swift-evolution 
>  wrote:
> 
> Dear swift-evolution denizens,
> 
> As you know from our announcement of Swift Open Source and our work on naming 
> guidelines, one of our goals for Swift 3 is to “drop NS” for Foundation. We 
> want to to make the cross-platform Foundation API that is available as part 
> of swift-corelibs feel like it is not tied to just Darwin targets. We also 
> want to reinforce the idea that new Foundation API must fit in with the 
> language, standard library, and the rapidly evolving design patterns we see 
> in the community.
> 
> You challenged us on one part of this plan: some Foundation API just doesn’t 
> “feel Swifty”, and a large part of the reason why is that it often does not 
> have the same value type behavior as other Swift types. We took this feedback 
> seriously, and I would like to share with you the start of an important 
> journey for some of the most commonly used APIs on all of our platforms: 
> adopting value semantics for key Foundation types.
> 
> We have been working on this for some time now, and the set of diffs that 
> result from this change is large. At this point, I am going to focus effort 
> on an overview of the high level goals and not the individual API of each new 
> type. In order to focus on delivering something up to our quality standards, 
> we are intentionally leaving some class types as-is until a future proposal. 
> If you don’t see your favorite class on the list — don’t despair. We are 
> going to iterate on this over time. I see this as the start of the process.
> 
> One process note: we are still trying to figure out the best way to integrate 
> changes to API that ship as part of the operating system (which includes 
> Foundation) into the swift-evolution review process. Swift-evolution is 
> normally focused on changes to functionality in the compiler or standard 
> library. In general, I don’t expect all new Foundation API introduced in the 
> Darwin/Objective-C framework to go through the open source process. However, 
> as we’ve brought up this topic here before, I felt it was important to bring 
> this particular change to the swift-evolution list.
> 
> As always I welcome your feedback.
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for-foundation.md
> 
> Thanks,
> - Tony
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Mutability for Foundation types in Swift

2016-04-22 Thread Charles Srstka via swift-evolution
> On Apr 22, 2016, at 5:05 PM, Greg Parker <gpar...@apple.com> wrote:
> 
>> On Apr 22, 2016, at 2:36 PM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> One comment:
>> 
>> "In the most common case where a developer does not provide a custom 
>> reference type, then the backing store is our existing NSData and 
>> NSMutableData implementations. This consolidates logic into one place and 
>> provides cheap bridging in many cases (see Bridging for more information).”
>> 
>> Would it not be more efficient to bridge to the C-based CFData and 
>> CFMutableData implementations instead, to avoid the object overhead?
> 
> Not necessarily. Foundation often has less overhead than CF nowadays.

That’s interesting; I hadn’t known that. What causes that? My understanding had 
always been that the NS and CF objects, being toll-free bridged to each other, 
shared the same default implementations, with the only difference being that 
the NS versions involved the overhead from objc_msgSend() as well as, in many 
cases, an autorelease.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Make Optional Requirements Objective-C-only

2016-04-25 Thread Charles Srstka via swift-evolution
> On Apr 25, 2016, at 11:49 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
>> (Tangentially, why not introduce a required "override" keyword for 
>> conforming types that implement a version of a member introduced in protocol 
>> extensions? This would match the class approach and enhance safety and 
>> intent.)
> 
> This is a commonly-requested feature that I don’t think we need. The TL;DR 
> version is that I feel like specifying the conformance explicitly (my type 
> Foo conforms to protocol P) already expresses intent, and the compiler should 
> help with the rest. I’ve recently been working on providing better warnings 
> for cases where one has tried to implement an optional requirement for a 
> protocol (but got the declaration wrong), and I think we can turn it on for 
> cases where one got a default implementation instead:

The trouble with this is that it can be quite non-obvious whether a method in a 
protocol is required or not. If you have this:

protocol Foo {
func bar()
func baz ()
}

extension Foo {
func bar() {}
}

it will generate this interface:

internal protocol Foo {
internal func bar()
internal func baz()
}

extension Foo {
internal func bar()
}

There’s no way to tell which method you actually have to implement, simply from 
looking at the protocol. When there are only two methods, this isn’t hard to 
figure out, but what if there are 25 methods, each with extensive header docs 
in front of the declaration, and only two of them are required? The only way to 
find the required ones would be to first completely search through the entire 
library and/or framework for extensions on this type. Then, you'd look at the 
first method in the protocol, scroll down to the extension, scour the extension 
for that method name, then scour any *other* extensions you’ve found for the 
method name, then scroll back up to the protocol, look at the next method. Now, 
repeat the whole thing until you’ve done it 25 times, and hope you haven’t 
failed to spot a method name in an extension somewhere.

The upshot of all this is that it’s pretty easy to accidentally implement a 
method on a protocol because you thought you had to, when actually you didn’t. 
Requiring “override” would at least prevent that, although IMO it would be best 
if there were some kind of annotation on the protocol’s interface letting you 
know if there were already a default implementation for that method, similar to 
Objective-C’s good old optional keyword.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0070: Make Optional Requirements Objective-C only

2016-04-27 Thread Charles Srstka via swift-evolution
> On Apr 27, 2016, at 9:30 AM, Andrew Bennett via swift-evolution 
>  wrote:
> 
> Sorry if this has been discussed, but have you considered dropping optional 
> entirely, making it throw, and a default implementation that throws a 
> selector not found exception?
> 
> This is approximately what you would expect using it in objc. I don't think 
> it has the complexity discussed in the proposals alternatives for other call 
> site issues.
> 
> If it throws you can call with "try?" to get similar functionality in most 
> cases.
> 
> This assumes that respondsToSelector doesn't pick up the Swift default 
> implementation.

Is there any case where you’d actually want to display a runtime error as a 
result of a delegate not implementing an optional method, though? Even setting 
aside that the method’s supposed to be optional, leaving out a needed delegate 
method seems more like a programmer error than a runtime error.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0070: Make Optional Requirements Objective-C only

2016-04-27 Thread Charles Srstka via swift-evolution
Why would you want lack of an optional method to be a fatal error, either?

Charles

> On Apr 27, 2016, at 5:29 PM, Andrew Bennett  wrote:
> 
> Hi Charles,
> 
> My initial idea just had a fatalError, without a throw. It's better IMO, but 
> less Swift-y. It's not obvious from the Swift protocol definition that this 
> could happen. I'm not sure if it's possible for the extension method to have 
> @noreturn or similar on it.
> 
> On Thursday, 28 April 2016, Charles Srstka  > wrote:
>> On Apr 27, 2016, at 9:30 AM, Andrew Bennett via swift-evolution 
>> > > wrote:
>> 
>> Sorry if this has been discussed, but have you considered dropping optional 
>> entirely, making it throw, and a default implementation that throws a 
>> selector not found exception?
>> 
>> This is approximately what you would expect using it in objc. I don't think 
>> it has the complexity discussed in the proposals alternatives for other call 
>> site issues.
>> 
>> If it throws you can call with "try?" to get similar functionality in most 
>> cases.
>> 
>> This assumes that respondsToSelector doesn't pick up the Swift default 
>> implementation.
> 
> Is there any case where you’d actually want to display a runtime error as a 
> result of a delegate not implementing an optional method, though? Even 
> setting aside that the method’s supposed to be optional, leaving out a needed 
> delegate method seems more like a programmer error than a runtime error.
> 
> Charles
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Requiring proactive overrides for default protocol implementations.

2016-04-27 Thread Charles Srstka via swift-evolution
I would prefer the “override” only apply to methods that already had default 
protocol implementations, because then it could help avoid the mistake of 
overriding a default implementation that you didn’t realize was there, thinking 
that this was a method that you needed to supply.

Charles

> On Apr 27, 2016, at 8:26 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> @Tod,
> 
> This was a concern when Java changed the behaviour of `@Override`, but it 
> didn't pan out. Everyone, even those with reservations, grew to like the new 
> behaviour. I think the much improved error messages from the compiler helped, 
> e.g.:
> 
> protocol ViewObserver { 
> func append(observer observer: Observer) 
> func remove(observer observer: Observer)
> func removeAll()
> }
> struct AViewObserver: ViewObserver {
> func apend(observer observer: Observer) {
> ...
> }
> func remove(observer observer: Observer) {
> ...
> }
> func removeAll() {
> ...
> }
> }
> 
> The only error you get at present with the above is that `AViewObserver` does 
> not conform to `ViewObserver`, it doesn't tell you why. With the change the 
> compiler would highlight that `apend` doesn't override `append` :(.
> 
> 
>   -- Howard.
> 
> On 28 April 2016 at 11:17, Tod Cunningham  > wrote:
> I think it would be odd and confusing to always have to use override when 
> implementing protocol methods (especially protocol methods without default 
> implementations).   To me override is telling me that there is another 
> implementation, and I am for lack of a better word overriding that 
> implementation.   However, for a protocol w/o a default implementation, there 
> is no implementation.  You aren’t overriding anything.  You are just 
> conforming to a signature.  Now protocol’s with default implementations there 
> could be a case made for using override.  Expect Swift current implementation 
> doesn't really override the default implementation, as shown in my example.  
> The other issues would be if I am overriding  something, I would expect to be 
> able to execute the default implementation from within my override.
> 
> It might be nice to have some syntax that would identify the protocol that is 
> being implemented at the point of the implementation. For example (although I 
> don't like this syntax):
>func (protocolname1, protocolname2) commonmethod() -> Void { .. the 
> implementation.. }
> 
> - Tod Cunningham
> 
> From: swift-evolution-boun...@swift.org 
>   > on behalf of Josh Parmenter via 
> swift-evolution >
> Sent: Wednesday, April 27, 2016 8:27 PM
> To: Howard Lovatt
> Cc: swift-evolution
> Subject: Re: [swift-evolution] [Pitch] Requiring proactive overrides for 
> default protocol implementations.
> 
> On Apr 27, 2016, at 17:23, Howard Lovatt via swift-evolution 
>   >> wrote:
> 
> I think that you should *always* have to write `override` when implementing a 
> protocol method, you can think of this as override an abstract declaration. 
> In particular I think the following should be enforced:
> 
> protocol A { func a() }
> extension A { override func a() { ... } }
> struct AnA: A { override func a() { ... } }
> 
> protocol B { func b() }
> struct AB: B { override func b() { ... } }
> 
> 
> I'm rather new to the list - but I would like to say that I agree with this. 
> I think it gives clarity both to code readability, and for learning the 
> language.
> Best
> Josh
> 
> I think this change will work out well since it mimics what happened in Java, 
> originally the Java annotation `@Override` was used much like `override` is 
> currently used in Swift. However it was problematic and was changed so that 
> you always add the annotation, as shown above (in the Swift context). One of 
> the big advantages of this change is that the error messages are much better 
> (this was very noticeable in Java).
> 
> This proposal has come up before on swift-evolution, so it obviously has some 
> support.
> 
> On Thursday, 28 April 2016, Erica Sadun via swift-evolution 
>   >> wrote:
> From the Swift Programming Language: Methods on a subclass that override the 
> superclass's implementation are marked with override-overriding a method by 
> accident, without override, is detected by the compiler as an error. The 
> compiler also detects 

Re: [swift-evolution] Proposal SE-0009 Reconsideration

2016-05-23 Thread Charles Srstka via swift-evolution
As another colorblind developer, this kind of is an issue. While I *can* 
discern colors, the only one that sticks out strongly is blue. If you’ve got 
reds, greens, browns, or oranges, my experience will be on a continuum from “I 
think that’s red?” in the best case, “I can figure this out if I 
accessibility-zoom it into a huge color patch” in the middle, and “Let me get 
out DigitalColorMeter” in the worst case. Purple, of course, is very hard to 
distinguish from blue. I guess grey is distinguishable, if you consider it a 
color. Other than that, syntax highlighting doesn’t do a lot for me.

Plus, I might end up having to use a different source editor sometimes, 
particularly when I’m doing a large refactor and Xcode is stuck in its 
“SourceKitService crash every time two characters are typed” thing. I’d really 
rather have things differentiable in the language itself rather than relying on 
external crutches.

Charles

> On May 23, 2016, at 11:43 AM, Jeff Kelley via swift-evolution 
>  wrote:
> 
> As a colorblind developer, this isn’t really an issue. The vast majority of 
> colorblind people can discern colors. As long as the IDE allows you to 
> customize which colors it displays, you can find a palette that will work 
> with your eyes (for my type of colorblindness, for instance, I have 
> difficulty differentiating blue and purple, so I wouldn’t use both in my 
> syntax highlighting color scheme). As long as color isn’t the only thing 
> differentiating on-screen elements, adding colors to syntax highlighting is 
> beneficial even to us colorblind developers. :)

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-24 Thread Charles Srstka via swift-evolution
> On May 24, 2016, at 5:45 PM, Haravikk via swift-evolution 
>  wrote:
> 
>> On 24 May 2016, at 21:14, Leonardo Pessoa > > wrote:
>> 
>> My first question here would be "what's the gain?" I understand
>> CollectionTypes and arrays may be something different but I myself
>> admit I don't know and wonder how that change would be a benefit to
>> us?
> 
> Instead of functions only accepting an Array, which is a specific type, they 
> would accept any collection type, including all the lazy collections.

Among other things, one practical advantage of this is that since ArraySlice 
conforms to CollectionType, one could simply subscript an array if they wanted 
to send only a subset of its contents to a method, without having to incur the 
performance cost of creating a new array.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal SE-0009 Reconsideration

2016-05-18 Thread Charles Srstka via swift-evolution
And that works about 30% of the time, if you’re being generous.

Charles

> On May 18, 2016, at 1:20 PM, Karl via swift-evolution 
>  wrote:
> 
> Since you’re using OSX - CMD + click, jumps to definition.
> 
>> On 18 May 2016, at 07:09, Krystof Vasa via swift-evolution 
>>  wrote:
>> 
>> Hi there,
>> 
>> I've been an OS X developer for over a decade now and was a huge fan of 
>> ObjC, implementing ObjC runtime into FreeBSD kernel as a intern at Cambridge 
>> University and my Masters thesis was a modular ObjC runtime that ran on Win 
>> 3.11. With the advance of Swift, it was clear to me, however, that this is a 
>> point to say goodbye to ObjC and move to Swift.
>> 
>> And so, I've migrated all my projects over 5 months into Swift, which is 
>> over 200 KLOC of code, with one project being 90 KLOC. This has lead 
>> unfortunately to various hiccups due to bugs in Swift, Xcode, compiler, 
>> where I was unable to build a project for a month, etc. - I've filed 84 bug 
>> reports at bugreport.apple.com over the past few months regarding developer 
>> tools (including Swift) and have begun closely watching the evolution of 
>> Swift.
>> 
>> While I strongly disagree with the rejection of SE-0009, I understood the 
>> reasoning that it's a boilerplate to keep adding self. in front of all 
>> variables. I personally always refer to self when accessing instance 
>> variables (and methods), unless they are private variables starting with 
>> underscore. I know the underscore thing isn't very Swift-y, but on the other 
>> hand, reading the code you immediately know you are dealing with a private 
>> instance variable, not something local.
>> 
>> This was until I spent 2 hours chasing a bug that was caused by the exact 
>> issue this proposal was trying to prevent. I was furious. 
>> 
>> a) When you read someone elses code and you see myVar.doSomething(), you 
>> assume it's refering to a local variable. Which is incredibly confusing, if 
>> this is an instance variable. Swift is all about compile-time checks and 
>> this is where it fails.
>> 
>> b) If you indeed decide not to go with this proposal, please consider adding 
>> a warning option. When you take a look at LLVM warning options, I bet there 
>> would be a place for this. Let the user decide. I personally would 
>> immediately turn it on on all my projects. Don't make it an error, make it a 
>> warning.
>> 
>> I speak to you as someone with quite a huge real-life experience with Swift, 
>> mainly in the last year - the question whether to force the reference to 
>> self is something that may be dividing the community, but I believe that 
>> most people with more developing experience would be all for this. At least 
>> as an option.
>> 
>> Sincerely yours,
>> 
>> Krystof Vasa
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Deprecate optionals in string interpolation

2016-05-18 Thread Charles Srstka via swift-evolution
+1 from me as well. All these “Optional(foo)” things showing up in user-facing 
strings are a pain, and since they don’t show up until runtime, it’s really 
easy to miss them.

Charles

> On May 18, 2016, at 1:50 PM, Krystof Vasa via swift-evolution 
>  wrote:
> 
> The string interpolation is one of the strong sides of Swift, but also one of 
> its weaknesses. 
> 
> It has happened to me more than once that I've used the interpolation with an 
> optional by mistake and the result is then far from the expected result. 
> 
> This happened mostly before Swift 2.0's guard expression, but has happened 
> since as well.
> 
> The user will seldomly want to really get the output "Optional(something)", 
> but is almost always expecting just "something". I believe this should be 
> addressed by a warning to force the user to check the expression to prevent 
> unwanted results. If you indeed want the output of an optional, it's almost 
> always better to use the ?? operator and supply a null value placeholder, 
> e.g. "\(myOptional ?? "<>")", or use myOptional.debugDescription - 
> which is a valid expression that will always return a non-optional value to 
> force the current behavior.
> 
> Krystof
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal SE-0009 Reconsideration

2016-05-18 Thread Charles Srstka via swift-evolution
Put me firmly in the pro-warning camp. If enforcing manual synthesis of ivars 
(something I never understood the brouhaha about) warranted a warning flag in 
clang, I think requiring self should at least merit consideration. It certainly 
has a much greater potential for bugs than automatic ivar synthesis.

Charles

> On May 18, 2016, at 11:44 PM, Krystof Vasa via swift-evolution 
>  wrote:
> 
> Thanks for the link, I'll definitely keep my eye on it, though since there 
> are two large camps siding with either side, I don't see the harm making this 
> proposal an optional warning of the compiler that would be off by default and 
> those wanting to stay on the safe side would enable this and get a warning.
> 
> BTW another example of what this would prevent:
> 
> On OS X, all views (NSView) have a print(_:) method. So whenever you write 
> within your code print("something"), it actually invokes the printing method 
> (since its argument is AnyObject?) - if you indeed want to print something to 
> the console, you need to use Swift.print("something") which is incredibly 
> annoying mostly when you forget about this and all of sudden you get print 
> dialogs instead of a log in the console.
> 
> Yes, it's shadowing, but with this one, you can't do anything about and there 
> will always be cases of shadowing - the more dangerous when you don't know 
> about them.
> 
> Krystof
> 
>> On May 19, 2016, at 6:32 AM, Félix Cloutier via swift-evolution 
>> > wrote:
>> 
>> That proposal might be one of the first early proposals to really get a lot 
>> of attention. My take out of the experience is that people (me included in 
>> this case) will yell very loudly if you try to enforce your coding standards 
>> through the compiler.
>> 
>> There is an open bug on SwiftLint 
>>  to add a rule that enforces 
>> using self to access member variables. It might be worth taking a look.
>> 
>> Félix
>> 
>>> Le 17 mai 2016 à 22:09:44, Krystof Vasa via swift-evolution 
>>> > a écrit :
>>> 
>>> Hi there,
>>> 
>>> I've been an OS X developer for over a decade now and was a huge fan of 
>>> ObjC, implementing ObjC runtime into FreeBSD kernel as a intern at 
>>> Cambridge University and my Masters thesis was a modular ObjC runtime that 
>>> ran on Win 3.11. With the advance of Swift, it was clear to me, however, 
>>> that this is a point to say goodbye to ObjC and move to Swift.
>>> 
>>> And so, I've migrated all my projects over 5 months into Swift, which is 
>>> over 200 KLOC of code, with one project being 90 KLOC. This has lead 
>>> unfortunately to various hiccups due to bugs in Swift, Xcode, compiler, 
>>> where I was unable to build a project for a month, etc. - I've filed 84 bug 
>>> reports at bugreport.apple.com  over the past 
>>> few months regarding developer tools (including Swift) and have begun 
>>> closely watching the evolution of Swift.
>>> 
>>> While I strongly disagree with the rejection of SE-0009, I understood the 
>>> reasoning that it's a boilerplate to keep adding self. in front of all 
>>> variables. I personally always refer to self when accessing instance 
>>> variables (and methods), unless they are private variables starting with 
>>> underscore. I know the underscore thing isn't very Swift-y, but on the 
>>> other hand, reading the code you immediately know you are dealing with a 
>>> private instance variable, not something local.
>>> 
>>> This was until I spent 2 hours chasing a bug that was caused by the exact 
>>> issue this proposal was trying to prevent. I was furious. 
>>> 
>>> a) When you read someone elses code and you see myVar.doSomething(), you 
>>> assume it's refering to a local variable. Which is incredibly confusing, if 
>>> this is an instance variable. Swift is all about compile-time checks and 
>>> this is where it fails.
>>> 
>>> b) If you indeed decide not to go with this proposal, please consider 
>>> adding a warning option. When you take a look at LLVM warning options, I 
>>> bet there would be a place for this. Let the user decide. I personally 
>>> would immediately turn it on on all my projects. Don't make it an error, 
>>> make it a warning.
>>> 
>>> I speak to you as someone with quite a huge real-life experience with 
>>> Swift, mainly in the last year - the question whether to force the 
>>> reference to self is something that may be dividing the community, but I 
>>> believe that most people with more developing experience would be all for 
>>> this. At least as an option.
>>> 
>>> Sincerely yours,
>>> 
>>> Krystof Vasa
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 

Re: [swift-evolution] Proposal SE-0009 Reconsideration

2016-05-19 Thread Charles Srstka via swift-evolution
> On May 19, 2016, at 2:15 PM, Michael Peternell via swift-evolution 
>  wrote:
> 
> The problem that SE-0009 tries to solve is that when looking at a line in 
> isolation, like
> 
>print(foo)
> 
> there is no way to tell wether foo is an iVar, a local var or a parameter.

Or whether print() is going to log something to the console, or open up the 
OS’s Print sheet.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [proposal] default returns

2016-05-10 Thread Charles Srstka via swift-evolution
> On May 10, 2016, at 7:11 PM, Eduardo Mourey Lopez Ne via swift-evolution 
>  wrote:
> 
> current:
> func myComplexOperation() -> Int {
>   //Some long complex code that might return some value
>   //Default return at the very end
>   return 0
> }
> 
> proposal:
> func myComplexOperation() -> Int {
>   //set the default return at the begging using the ‘default’ keyword or 
> some other keyword
>   default 0
>   //Some long complex code that might return a value
>   //if the end of the function is reached, return the default
> }
> 
> The other alternative will be to allow naming the return value
> proposal2:
> func myComplexOperation() -> result:Int {
>//set the default return at the begging using the output variable name
>   result = 0
>   //Some long complex code that might return some value
> }
> 
> Another alternative will be to set the default value directly like and 
> optional parameter
> proposal3:
> func myComplexOperation() -> Int = 0 {
>   //Some long complex code that might return some value
> }

Is this really that much more convenient than:

func myComplexOperation() -> Int {
let default = 0

// do something

return default
}

to justify a whole language feature?

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [proposal] extra if syntax

2016-05-10 Thread Charles Srstka via swift-evolution
> On May 10, 2016, at 1:10 PM, MobileSoft (Piotr) via swift-evolution 
>  wrote:
> 
> I think that should be added new ‘postfix’ if syntax:
> a = 5 if b == x
> 
> the code will be better readable. For example:
> 
> a = 5 if b == x
> c = 6
> d = 8
> e = 10 if y == true
> f = 12
> 
> in this situation all assigns are on the same, left side.

What’s wrong with:

a = (b == x ? 5 : whateverElseBShouldBe)
c = 6
d = 8
e = (y ? 10 : whateverElseEShouldBe)
f = 12

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Why can't protocols define constants or subtypes?

2016-05-11 Thread Charles Srstka via swift-evolution
With a class or a struct, I can nest constants and subtypes within the type, 
like so:

class MyWidget {
static let SomeConstant = “This string is useful to subclasses of 
MyWidget somehow"

enum Type {
case Cog
case Sprocket
}

enum Error {
case SomethingWentWrong
case SomethingElseWentWrong
}

var type: Self.Type // This doesn’t work yet, but it should after 
SE-0068 is implemented

func doSomething() throws // might throw one of the errors above
}

This is nice for namespacing, and it makes the code clear and organized.

However, if I convert this to a protocol-based approach, I have to do this the 
old Objective-C way:

static let MyWidgetSomeConstant = “This string is useful to implementers of 
MyWidget somehow"

enum MyWidgetType {
case Cog
case Sprocket
}

enum MyWidgetError {
case SomethingWentWrong
case SomethingElseWentWrong
}

protocol MyWidget {
var type: MyWidgetType

func doSomething() throws // might throw one of the errors above
}

This is ugly, and pollutes the global namespace with things that are only 
interesting to users and implementers of MyWidget. Is there a reason behind 
this? It seems that it could be useful to define constants and subtypes that 
could be useful for implementers of a protocol.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Winding down the Swift 3 release

2016-05-16 Thread Charles Srstka via swift-evolution
> On May 16, 2016, at 4:27 PM, Eric Wing via swift-evolution 
>  wrote:
> 
>> I'm not an expert in the Linux communities needs and desires.  That said,
>> from what I understand, they don’t care at all about ABI stability, since
>> everything is typically built from source.
>> 
>> -Chris
>> 
>> 
> 
> Not exactly true. (I care.)
> 
> Video games (e.g. Steam/Linux) care deeply about ABI stability. And
> Android cares deeply about ABI stability. Also, kind of emergent
> behavior, Raspberry Pi Raspbian has kind of built a platform that
> happens to have some ABI stability for now.
> 
> Thanks,
> Eric

ABI stability is also central to eventually removing the need to always ship 
the runtime along with our binaries.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-12 Thread Charles Srstka via swift-evolution
> On May 6, 2016, at 10:16 PM, Charles Srstka <cocoa...@charlessoft.com> wrote:
> 
>> On May 5, 2016, at 2:06 PM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I formerly posted a less-fleshed-out version of this in the “Reducing 
>> bridging magic” thread, but I thought this might warrant its own pitch. What 
>> do you all think?
>> 
>> MOTIVATION:
>> 
>> Over the past couple of years, Swift has made great strides toward seamless 
>> interoperability with existing Objective-C APIs, and with SE-0005, SE-0033, 
>> SE-0057, SE-0062, SE-0064, and SE-0070, seems poised to become even better 
>> in that regard. However, there still exists one major pain point when going 
>> back and forth between Swift and Objective-C, and that lies in the area of 
>> error reporting. Passing errors between Objective-C and Swift APIs is 
>> currently quite awkward, for several reasons:
>> 
>> - The Swift-approved mechanism for reporting errors is a protocol named 
>> ErrorType (ErrorProtocol in the latest sources). However, Objective-C 
>> represent errors using a class named NSError. In addition to being a 
>> reference type, which feels quite unnatural for an error object by Swift’s 
>> conventions, NSError follows a completely paradigm from what most 
>> ErrorProtocol objects use to store errors, using a string-based domain and 
>> and integer code, along with a userInfo dictionary to store information to 
>> be presented to the user. While the domain and code are available as methods 
>> on ErrorProtocol, they are prefixed with underscores, and there is no direct 
>> equivalent to userInfo.
>> 
>> - Unlike other Objective-C classes like NSString and NSArray which are 
>> consistently bridged to value types when presenting Objective-C interfaces 
>> to Swift, the handling of NSError objects is inconsistent. Objective-C APIs 
>> which return an error by reference using an autoreleasing NSError ** pointer 
>> are converted to use the Swift try/catch mechanism, presenting the returned 
>> error as an ErrorProtocol (which is actually an NSError). Similarly, Swift 
>> APIs using try/catch are presented to Objective-C as autoreleasing NSError 
>> ** pointers, and the ErrorProtocol-conforming error is converted to an 
>> NSError when it is called by Objective-C. However, when passing around error 
>> objects in any way other than these, the errors are not bridged. An 
>> Objective-C API that takes an NSError, such as NSApp’s -presentError: 
>> method, still leaves NSError as the type in the interface presented to 
>> Swift, as do the many asynchronous APIs in Cocoa that return an NSError as 
>> one of the arguments to a completion handler. Swift APIs that accept 
>> ErrorProtocols, on the other hand, are not presented to Objective-C at all, 
>> necessitating any such APIs also be declared to take NSErrors.
>> 
>> - To convert ErrorProtocols to NSErrors, Swift provides a bridging 
>> mechanism, invoked via “as NSError”, which wraps the error in a private 
>> NSError subclass class called _SwiftNativeNSError. This subclass can be cast 
>> back to the original error type, thus returning the original wrapped error. 
>> When a Swift API that is marked “throws” is called from Objective-C and then 
>> throws an error, the same bridging mechanism is invoked. However, this 
>> bridging is not very useful, since Cocoa tends to use NSError’s userInfo 
>> dictionary to present error information to the user, and ErrorProtocol 
>> contains no equivalent to the userInfo dictionary. The result of this is 
>> that when a Swift API throws an error, and this error is passed to Cocoa, 
>> the user tends to get a generic error message instead of something actually 
>> useful.
>> 
>> - The above problem means that a Swift developer must be very careful never 
>> to use “as NSError”, and to be sure to construct an NSError when throwing an 
>> error in an API that may be called from Objective-C, rather than simply 
>> throwing the error directly, or else the error will not be properly 
>> presented. If the developer makes a mistake here, it will not be known until 
>> runtime. I have personally wasted quite a bit of time trying to hunt down 
>> points in a complicated program where an error was accidentally converted to 
>> NSError via the bridge rather than explicitly.
>> 
>> - The same problem also puts the Swift developer between a rock and a hard 
>> place, if they have other code that wants to check these errors. In a 
>> pure-Swift program, che

Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-14 Thread Charles Srstka via swift-evolution
> On May 14, 2016, at 3:51 AM, Michael Peternell  
> wrote:
> 
> For interoperability, ErrorType and NSError should be toll-free-bridged, like 
> CFStringRef and NSString. Converting between them should be a no-op at 
> runtime.

That would be technically infeasible without restricting ErrorType to reference 
types using the Objective-C runtime, which I don’t think anyone wants to do.

> I prefer runtime/ABI consistency over syntax/language consistency. 
> MyErrorType2 should be represented as an NSError with domain @"MyErrorType2", 
> whatever code is defined in that error type, and if you want userInfo you 
> have to create the beast as an NSError object in the first place. I think 
> userInfo is not visible in the Swift-enum-representation. If you want to have 
> a Swift Error representation that includes userInfo, you'd have to either 
> change the architecture or introduce special support on the language level 
> (e.g. a magic `er.userInfo` of type `Dictionary` for every 
> `er: ErrorType` and a `er.withUserInfo(userInfo)` to add a userInfo 
> dictionary to an error type: e.g. 
> `MyErrorType2.fooConditionFound.withUserInfo([NSLocalizedDescriptionKey: 
> "that was really bad"])` and maybe even a convenience method as a protocol 
> extension like 
> `MyErrorType.fooConditionFound.withLocalizedDescription(localizedString: 
> "ReallyBad")`.

Adding a userInfo property to the protocol declaration (with a default 
implementation for those that don’t want to implement it) would solve this 
without any low-level hacking.

> And the key of a dictionary should really always be a String, not just an 
> NSObject.)

I actually agree; I used [NSObject : AnyObject] since that’s what NSError’s 
userInfo is currently defined as. Putting [String : AnyObject] in the protocol 
instead would be fine, although you’d have to do a little sanity checking in 
the bridging to filter out non-string keys from the dictionary.

> (I know if you have something like `case SpecialError(Int)` in your ErrorType 
> declaration, the above method does not work; you'd have to create an 
> NSError-subclass for it. Or maybe not? Just add a "SpecialError_arg0" key to 
> userInfo, value can be an NSNumber? There are more edge cases here but they 
> are all solvable.)
> 
> On the other hand, I don't think that enumerations in general should support 
> instance variables. One of the nice things for an enum is that I as a 
> programmer can always be sure that it *is* just an enum, and nothing else. 
> Adding iVars to enums would effectively turning enums to structs, and each 
> time I see a switch statement I'll have to think "is this really all? or is 
> there some stealth value attached to this enum? is every .MadeAMistake object 
> always the same?" Keeping the inconsistency constrained to the ErrorType is 
> much nicer than turning every enum into a struct.

Adding instance variables to enums is not necessary for this. The userInfo here 
can be implemented as a computed property, as it would be in enums (in classes 
and structs, of course, it would be up to the developer whether to make it a 
stored or computed property).

> There will always be rough edges when converting between two languages, 
> that's unavoidable. Try to translate a text that contains a lot of the words 
> "safety" and "security" into German. Good luck, they both translate to the 
> same word. And so there also cannot be a perfectly consistent translation 
> between ErrorType and NSError. If you want to achieve a good translation, 
> you'd have to change the ErrorType to something different. E.g. a special 
> language construct `def-error MyErrorType { case MadeAMistake; case 
> RanOutOfCake }` - matching works the same as now and you have a userInfo 
> property. And on non-objc-platforms, the NSError() name becomes unavailable 
> and .userInfo always returns `[:]`. I'm not saying that this would be a 
> beautiful solution; I'm saying that there is no beautiful solution to this 
> problem.


I think that creating wrappers for both directions could work pretty well if we 
had a userInfo property on ErrorType/Protocol. We’ve got one going in one 
direction already.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-13 Thread Charles Srstka via swift-evolution
On May 14, 2016, at 12:19 AM, Jon Shier via swift-evolution 
 wrote:
> 
> Charles:
>   I appreciate the attempt to minimize a current pain point and I agree 
> on most of your analysis of the current NSError bridging but I think your 
> proposal is fundamentally flawed. By forcing the core error type to have 
> properties from NSError, you’re essentially finalizing what all error types 
> in Swift should look like. Error domains, codes, and info dictionaries are 
> not Swift, and forcing every error produced in Swift to have those properties 
> is a regression from the freedom ErrorType has given us. No native Swift 
> error type I’ve seen so far has chosen to replicate those properties, and for 
> good reason: they are a relic of C which have no place in Swift. There are 
> far better error designs out there. If you want to propose a strong type of 
> error for Swift, go ahead, but it should be thoroughly inspired by Swift, not 
> driven by a desire to ease bridging to NSError.

Nothing is forced at all, any more than they are currently. The thing to 
remember is that ErrorProtocol *already* defines properties for error domains 
and codes:

public protocol ErrorProtocol {
  var _domain: String { get }
  var _code: Int { get }
}

Thus, the statement that no native Swift error type has these properties could 
not be farther from the truth, as in fact, *every* Swift error type has these 
two properties (and several prominent error types in the standard library 
provide specific values for these properties as well; POSIXError and 
NSCocoaError come to mind). The reason many Swift developers haven’t noticed 
this fact is because the properties have default implementations, which means 
that if you don’t have a specific need to override them, you never have to deal 
with them. Adding a userInfo property, which also has a default implementation 
(returning an empty dictionary), will therefore not take away any of the 
freedom of ErrorType, or really cause any difference at all to a developer who 
is not interested in providing userInfo values on his/her errors.

What the proposal will do, on the other hand, is give a lot of that freedom 
*back*. The fact of the matter is that the entire error-reporting mechanism is 
currently based on NSError. If you have a method which can return an error, and 
you want that error to be presentable to the user in a form more expressive 
than “MyApp.MyErrorType error 2”, you currently have only two choices: 1) 
create some home-grown mechanism to convert your errors to NSErrors, and be 
sure to invoke that mechanism when throwing from any method that could 
conceivably be called from Objective-C, or 2) just use NSErrors all the way 
down, foregoing the use of native Swift errors at all. My proposal would allow 
the free and unlimited use of Swift native errors everywhere errors are a 
possibility with no drawbacks, since if an error needed to be made into a 
human-readable form, this would only be a simple matter of defining a userInfo 
property on the error type, even if much later down the line, and would not 
necessitate adding an NSError conversion at every throw-site in the program. 
Indeed, this proposal will actually *remove* a lot of NSError-based thinking 
from the actual code, and localize all such considerations to a relatively 
small area, to such extent as they are needed.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-14 Thread Charles Srstka via swift-evolution
> On May 14, 2016, at 1:45 AM, Jon Shier via swift-evolution 
>  wrote:
> 
> Charles:
>   Foundation error reporting is based on NSError, nothing else. In none 
> of my apps have I used my own NSError’s and in the few frameworks I use or 
> maintain, few use NSError, and then only to avoid having to declare a custom 
> error type, to make the API perhaps a bit more familiar to consumers.

All of the error-handling mechanisms in Cocoa are NSError-based. 
-[NSApplication presentError:], -[NSDocument presentError:], and the like all 
take NSErrors.

> All your concern about conversion to and from NSErrors is largely irrelevant 
> to anyone who isn’t using Swift from Objective-C on a regular basis. It’s 
> utterly irrelevant to the native Swift programmer. I’m not sure where your 
> issue about presenting non-NSError’s come from, since the mechanisms to 
> present an error would have to be custom written no matter the error type.

Anyone who writes Cocoa apps on OS X or iOS using Swift is most certainly using 
Swift from Objective-C on a regular basis, because all of the underlying 
frameworks are Objective-C. For example, suppose you have a document-based 
application:

class MyDocument: NSDocument {
enum Error: ErrorType {
case MadeAMistake
case RanOutOfCake
}

…

readFromData(data: NSData, ofType: String) {
…

if someFailureCondition {
throw Error.RanOutOfCake
}

...
}

...
}

The readFromData method above will be called by Objective-C, since the internal 
NSDocument mechanism will be the one calling it. Since it will have no idea how 
to represent that, the error dialog box that appears will simply say something 
unhelpful like “MyApp.MyDocument.Error error 1”. Now, there are two ways to 
solve this, both of which involve throwing an NSError rather than a custom 
error type:

Solution 1: Get rid of the ErrorType.

class MyDocument: NSDocument {
let ErrorDomain = “MyApp.MyDocument”
enum ErrorCode: Int {
case MadeAMistake = 1
case RanOutOfCake = 2
}

…

readFromData(data: NSData, ofType: String) {
…

if someFailureCondition {
let userInfo = [NSLocalizedFailureReasonErrorKey: 
NSLocalizedString(“Looks like we ran out of cake.”, comment: “Ran out of cake”)]
throw NSError(domain: ErrorDomain, code: 
ErrorCode.RanOutOfCake.rawValue, userInfo: userInfo)
}

...
}

...
}

This has a couple of problems. First, it forces us to use NSError. Second, it’s 
ugly. Imagine a method with many possible failure points, all filled with the 
userInfo building above.

The second solution is a little better:

class MyDocument: NSDocument {
enum Error: ErrorType {
let ErrorDomain = “MyApp.MyDocument”

case MadeAMistake
case RanOutOfCake

func toNSError() -> NSError {
let failureReason: String
let code: Int

switch self {
case .MadeAMistake:
failureReason = NSLocalizedString(“Looks like we made a 
mistake.”, comment: “Made a mistake”)
code = 1
case .RanOutOfCake:
failureReason = NSLocalizedString(“Looks like we ran out of 
cake.”, comment: “Ran out of cake”)
code = 2
}

let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]

return NSError(domain: self.ErrorDomain, code: code, userInfo: 
userInfo)
}
}

…

readFromData(data: NSData, ofType: String) {
…

if someFailureCondition {
throw Error.RanOutOfCake.toNSError()
}

...
}

...
}

The good news is that now the ugliness is removed from the actual program code 
and confined to the error type’s declaration. The bad news is that if we forget 
to put .toNSError() on an error we throw somewhere and that bubbles back to 
Cocoa, the user gets a meaningless error message. Furthermore, if we call 
through to some other error-throwing method, we have to catch and convert any 
errors it might throw:

readFromData(data: NSData, ofType: String) {
…

do {
try somethingThatThrows()
} catch {
if let myError = error as? Error {
throw myError.toNSError()
} else if let someOtherError = error as? SomeOtherErrorType {
// convert to NSError somehow
} else if let yetAnotherError = …
etc. etc. etc.
} else {
throw error
}
}

…

}

At this point it’s probably just to use NSError all the way through. :-/

With my proposal, all you’d do is this:

class MyDocument: NSDocument {
enum Error: ErrorType {
case MadeAMistake
case RanOutOfCake

var userInfo: [NSObject : AnyObject] {
let failureReason: String

switch self {
case .MadeAMistake:
   

Re: [swift-evolution] [Pitch] Reducing the bridging magic in dynamic casts

2016-05-03 Thread Charles Srstka via swift-evolution
Here’s another argument in favor of the pitch:

Take an array:

let array = ["Foo", "Bar”]

We can convert this to an NSArray via the bridge:

let nsArray = array as NSArray

We can also convert this to a CFArray:

let cfArray = array as CFArray

Now, let’s convert them back.

let nsUntypedArray = nsArray as Array
let cfUntypedArray = cfArray as Array

This works, but both arrays are now Array, which probably isn’t what 
we want. Since Swift arrays care about type, and NS/CFArrays generally don’t, 
we’ll want to do a check when converting them back:

let nsToNativeArray = nsArray as? Array
let cfToNativeArray = cfArray as? Array

Checking the value of the first one there, we get a nice Optional(["Foo", 
"Bar”]), as expected. However, checking the second one reveals that it now 
contains *nil!* Worse, the bug won’t be discovered until runtime, and may be 
hard to track down, since the code above *looks* fine.

Adding an intermediate cast to NSArray, of course, makes it work fine:

let cfToNativeArray = cfArray as NSArray? as? Array // Optional(["Foo", 
"Bar"])

This may be a bug, maybe even a known one. However, if this had been done via 
initializers on Array rather than via bridging magic, the compiler would have 
thrown a type error when we tried to pass a CFArray to Array’s initializer if 
Array didn’t have an initializer that took a CFArray. The bridge, however, just 
cheerfully returns nil at runtime, leaving you with no idea something’s wrong 
until it all blows up mysteriously at runtime.

So basically, I guess I’m +1 on the pitch.

Charles

> On Apr 29, 2016, at 5:00 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> When we introduced Swift, we wanted to provide value types for common 
> containers, with the safety and state isolation benefits they provide, while 
> still working well with the reference-oriented world of Cocoa. To that end, 
> we invested a lot of work into bridging between Swift’s value semantics 
> containers and their analogous Cocoa container classes. This bridging 
> consisted of several pieces in the language, the compiler, and the runtime:
> 
> Importer bridging, importing Objective-C APIs that take and return NSString, 
> NSArray, NSDictionary and NSSet so that they take and return Swift’s 
> analogous value types instead.
> 
> Originally, the language allowed implicit conversions in both directions 
> between Swift value types and their analogous classes. We’ve been working on 
> phasing the implicit conversions out—we removed the object-to-value implicit 
> conversion in Swift 1.2, and propose to remove the other direction in 
> SE–0072—but the conversions can still be performed by an explicit coercion 
> string as NSString. These required-explicit as coercions don’t otherwise 
> exist in the language, since as generally is used to force coercions that can 
> also happen implicitly, and value-preserving conversions are more 
> idiomatically performed by constructors in the standard library.
> 
> The runtime supports dynamic bridging casts. If you have a value that’s 
> dynamically of a Swift value type, and try to as?, as!, or is-cast it to its 
> bridged Cocoa class type, the cast will succeed, and the runtime will apply 
> the bridging conversion:
> 
> // An Any that dynamically contains a value "foo": String
> let x: Any = "foo"
> // Cast succeeds and produces the bridged "foo": NSString
> let y = x as! NSString 
> Since Swift first came out, Cocoa has done a great job of “Swiftification”, 
> aided by new Objective-C features like nullability and lightweight generics 
> that have greatly improved the up-front quality of importer-bridged APIs. 
> This has let us deemphasize and gradually remove the special case implicit 
> conversions from the language. I think it’s time to consider extricating them 
> from the dynamic type system as well, making it so that as?, as!, and is 
> casts only concern themselves with typechecks, and transitioning to using 
> standard initializers and methods for performing bridging conversions. I’d 
> like to propose the following changes:
> 
> Dynamic casts as?, as! and is should no longer perform bridging conversions 
> between value types and Cocoa classes.
> Coercion syntax as should no longer be used to explicitly force certain 
> bridging conversions.
> To replace this functionality, we should add initializers to bridged value 
> types and classes that perform the value-preserving bridging operations.
> The Rules of as[?]
> 
> Our original goal implementing this behavior into the dynamic casting 
> machinery was to preserve some transitivity identities between implicit 
> conversions and casts that users could reason about, including:
> 
> x as! T as! U === x as! U, if x as! T succeeds. Casting to a type U should 
> succeed and give the same result for any derived cast result.
> x as! T as U === x as! U. If T is coercible to U, then you should get the 
> same result by casting to Tand coercing to U as by 

Re: [swift-evolution] [Review] SE-0060: Enforcing order of defaulted parameters

2016-05-03 Thread Charles Srstka via swift-evolution
Count me among those who had no idea this feature even existed.

The thing about the current behavior that strikes me as odd is that it only 
applies to parameters with default values. So foo(a: Int = 1, b: Int = 2) is 
reorderable, whereas foo(a: Int, b: Int) is not. This seems fairly inconsistent 
and quite weird, given that both forms contain the same amount of information 
that would be pertinent to determining order. So the behavior should probably 
change one way or the other; either remove it entirely, or extend it to labeled 
parameters without defaults.

Charles

> On May 3, 2016, at 10:52 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0060: Enforcing order of defaulted parameters" begins now 
> and runs through May 9. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0060-defaulted-parameter-order.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0080: Failable Numeric Conversion Initializers

2016-05-03 Thread Charles Srstka via swift-evolution
Is the proposal to add these initializers to protocols like IntegerType, or 
just to individually add them to each of the numeric types? It’s unclear from 
the proposal, but in case that question hasn’t been decided yet, I’d like to 
vote for putting them in the protocols. It’s bugged me for a while that 
IntegerType doesn’t contain any of the existing initializers, even though every 
single type that conforms to it contains them, and even though 
FloatingPointType also contains them. Having support for these initializers in 
the protocol lets you do things like initialize generalized integer types in 
generic functions, which can be handy sometimes.

Charles

> On May 3, 2016, at 10:57 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0080: Failable Numeric Conversion Initializers" begins now 
> and runs through May 9. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0080-failable-numeric-initializers.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-06 Thread Charles Srstka via swift-evolution
> On May 5, 2016, at 2:06 PM, Charles Srstka via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> I formerly posted a less-fleshed-out version of this in the “Reducing 
> bridging magic” thread, but I thought this might warrant its own pitch. What 
> do you all think?
> 
> MOTIVATION:
> 
> Over the past couple of years, Swift has made great strides toward seamless 
> interoperability with existing Objective-C APIs, and with SE-0005, SE-0033, 
> SE-0057, SE-0062, SE-0064, and SE-0070, seems poised to become even better in 
> that regard. However, there still exists one major pain point when going back 
> and forth between Swift and Objective-C, and that lies in the area of error 
> reporting. Passing errors between Objective-C and Swift APIs is currently 
> quite awkward, for several reasons:
> 
> - The Swift-approved mechanism for reporting errors is a protocol named 
> ErrorType (ErrorProtocol in the latest sources). However, Objective-C 
> represent errors using a class named NSError. In addition to being a 
> reference type, which feels quite unnatural for an error object by Swift’s 
> conventions, NSError follows a completely paradigm from what most 
> ErrorProtocol objects use to store errors, using a string-based domain and 
> and integer code, along with a userInfo dictionary to store information to be 
> presented to the user. While the domain and code are available as methods on 
> ErrorProtocol, they are prefixed with underscores, and there is no direct 
> equivalent to userInfo.
> 
> - Unlike other Objective-C classes like NSString and NSArray which are 
> consistently bridged to value types when presenting Objective-C interfaces to 
> Swift, the handling of NSError objects is inconsistent. Objective-C APIs 
> which return an error by reference using an autoreleasing NSError ** pointer 
> are converted to use the Swift try/catch mechanism, presenting the returned 
> error as an ErrorProtocol (which is actually an NSError). Similarly, Swift 
> APIs using try/catch are presented to Objective-C as autoreleasing NSError ** 
> pointers, and the ErrorProtocol-conforming error is converted to an NSError 
> when it is called by Objective-C. However, when passing around error objects 
> in any way other than these, the errors are not bridged. An Objective-C API 
> that takes an NSError, such as NSApp’s -presentError: method, still leaves 
> NSError as the type in the interface presented to Swift, as do the many 
> asynchronous APIs in Cocoa that return an NSError as one of the arguments to 
> a completion handler. Swift APIs that accept ErrorProtocols, on the other 
> hand, are not presented to Objective-C at all, necessitating any such APIs 
> also be declared to take NSErrors.
> 
> - To convert ErrorProtocols to NSErrors, Swift provides a bridging mechanism, 
> invoked via “as NSError”, which wraps the error in a private NSError subclass 
> class called _SwiftNativeNSError. This subclass can be cast back to the 
> original error type, thus returning the original wrapped error. When a Swift 
> API that is marked “throws” is called from Objective-C and then throws an 
> error, the same bridging mechanism is invoked. However, this bridging is not 
> very useful, since Cocoa tends to use NSError’s userInfo dictionary to 
> present error information to the user, and ErrorProtocol contains no 
> equivalent to the userInfo dictionary. The result of this is that when a 
> Swift API throws an error, and this error is passed to Cocoa, the user tends 
> to get a generic error message instead of something actually useful.
> 
> - The above problem means that a Swift developer must be very careful never 
> to use “as NSError”, and to be sure to construct an NSError when throwing an 
> error in an API that may be called from Objective-C, rather than simply 
> throwing the error directly, or else the error will not be properly 
> presented. If the developer makes a mistake here, it will not be known until 
> runtime. I have personally wasted quite a bit of time trying to hunt down 
> points in a complicated program where an error was accidentally converted to 
> NSError via the bridge rather than explicitly.
> 
> - The same problem also puts the Swift developer between a rock and a hard 
> place, if they have other code that wants to check these errors. In a 
> pure-Swift program, checking against a particular error can often be done 
> simply via an equality check. If the error has been converted to NSError via 
> the bridge, this also works, since the bridge will return the original Swift 
> error when casted. However, if the API that threw the error has been 
> conscientious about constructing an NSError to avoid the userInfo issue, the 
> NSError will not be easily castable b

Re: [swift-evolution] [Accepted] SE-0072: Fully eliminate implicit bridging conversions from Swift

2016-05-06 Thread Charles Srstka via swift-evolution
> On May 6, 2016, at 3:15 PM, Joe Groff via swift-evolution 
>  wrote:
> 
>> On May 6, 2016, at 12:21 PM, Jacob Bandes-Storch via swift-evolution 
>> > wrote:
>> 
>> Does this affect the ability to use "x as? Int" (and similar) when x is an 
>> NSNumber?
> 
> No, this only affects compile-time implicit conversions. I proposed changing 
> the runtime behavior of dynamic casts in SE-0083:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0083-remove-bridging-from-dynamic-casts.md
>  
> 
I’d just like to throw in that the ability to use “x as? Int” when x is an 
NSNumber is terrible.

let num: AnyObject = NSNumber(int: 5)

let int = num as? Int   // 5
let float = num as? Float   // 5
let int32 = num as? Int32   // nil!

Completely unexpected failure, and you’ll never know about it until runtime.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Reducing the bridging magic in dynamic casts

2016-05-02 Thread Charles Srstka via swift-evolution
> On May 2, 2016, at 4:48 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
>> On May 2, 2016, at 3:45 PM, Chris Lattner via swift-evolution 
>> > wrote:
>>> NSError bridging can also be extracted from the runtime, and the same 
>>> functionality exposed as a factory initializer on NSError:
>>> 
>> 
>> I think that this proposal is overall really great, but what does it do to 
>> the “catch let x as NSError” pattern?  What is the replacement?  If the 
>> result is ugly, we may have to subset out NSError out of this pass, and 
>> handle it specifically with improvements to the error bridging story.
> 
> Grant me the serenity to accept the `NSError` I cannot change and the courage 
> to change the bridging conversions I should. Grant me the wisdom to know the 
> difference between a partial solution that offers a cleaner more predictable 
> interface set now and a full solution that cannot be achieved in a reasonable 
> timeframe.
> 
> -- E

Among the things that Billy Pilgrim could not change were the past, the 
present, and the future. Hopefully we have better luck, because the ErrorType 
to NSError bridging is currently a bit buggy.

Have a look at this code, and take a guess at what the results should be:

import Foundation

extension ErrorType {
public func toNSError() -> NSError {
return self as NSError
}
}

let error = NSError(domain: "Foo", code: -1, userInfo: 
[NSLocalizedFailureReasonErrorKey : "Something went wrong"])

let ns = error.toNSError()

print("Type of error was \(error.dynamicType), type of ns is \(ns.dynamicType)")

print("error's user info: \(error.userInfo)")
print("ns user info: \(ns.userInfo)”)

--

The results are a bit surprising:

Type of error was NSError, type of ns is _SwiftNativeNSError
error's user info: [NSLocalizedFailureReason: Something went wrong]
ns user info: [:]

What happened was:

1. The toNSError() method showed up for our NSError, since NSError is presented 
to Swift as conforming to ErrorType. 

2. However, due to a lack of dynamism, the code in the extension assumes that 
we have a Swift native error and *not* an NSError, so it goes ahead and wraps 
the NSError inside another NSError.

3. And since Swift doesn’t currently do anything to address the userInfo field, 
the userInfo that our error had gets chopped off.

Whoops.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Reducing the bridging magic in dynamic casts

2016-05-02 Thread Charles Srstka via swift-evolution
> On May 2, 2016, at 5:53 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> I can't think of any problems that would block us from doing that today. It'd 
> be pretty easy to write an ErrorProtocol extension that just forwards 
> NSError's interface via bridging, and I bet that'd cover most use cases for 
> 'as NSError':
> 
> extension ErrorProtocol {
>  var domain: String { return NSError(self).domain }
>  var code: Int { return NSError(self).code }
>  var userInfo: [String: AnyObject] { return NSError(self).userInfo }
>  /* etc. */
> }
> 
> -Joe

This could be fantastic if it accompanied the addition to ErrorProtocol of an 
“userInfo” property (or even _userInfo, although I’d really prefer that all 
three of these be de-underscored) that NSError(self) would pick up on when 
doing the conversion. Otherwise, we’re just going to have to keep on using 
custom .toNSError() methods instead of the official way, so it won’t matter if 
the latter is “as NSError” or “NSError(foo)” or something else.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Consistent bridging for NSErrors at the language boundary

2016-05-09 Thread Charles Srstka via swift-evolution
Anyone have any thoughts, opinions, etc. on this? I find it kind of strange 
that I’ve received off-list feedback from within Apple, but so far it’s been 
generally ignored publicly on the list. Surely I’m not the only one who cares 
about the lack of parity between NSError and ErrorProtocol.

Charles

> On May 6, 2016, at 10:16 PM, Charles Srstka <cocoa...@charlessoft.com> wrote:
> 
>> On May 5, 2016, at 2:06 PM, Charles Srstka via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I formerly posted a less-fleshed-out version of this in the “Reducing 
>> bridging magic” thread, but I thought this might warrant its own pitch. What 
>> do you all think?
>> 
>> MOTIVATION:
>> 
>> Over the past couple of years, Swift has made great strides toward seamless 
>> interoperability with existing Objective-C APIs, and with SE-0005, SE-0033, 
>> SE-0057, SE-0062, SE-0064, and SE-0070, seems poised to become even better 
>> in that regard. However, there still exists one major pain point when going 
>> back and forth between Swift and Objective-C, and that lies in the area of 
>> error reporting. Passing errors between Objective-C and Swift APIs is 
>> currently quite awkward, for several reasons:
>> 
>> - The Swift-approved mechanism for reporting errors is a protocol named 
>> ErrorType (ErrorProtocol in the latest sources). However, Objective-C 
>> represent errors using a class named NSError. In addition to being a 
>> reference type, which feels quite unnatural for an error object by Swift’s 
>> conventions, NSError follows a completely paradigm from what most 
>> ErrorProtocol objects use to store errors, using a string-based domain and 
>> and integer code, along with a userInfo dictionary to store information to 
>> be presented to the user. While the domain and code are available as methods 
>> on ErrorProtocol, they are prefixed with underscores, and there is no direct 
>> equivalent to userInfo.
>> 
>> - Unlike other Objective-C classes like NSString and NSArray which are 
>> consistently bridged to value types when presenting Objective-C interfaces 
>> to Swift, the handling of NSError objects is inconsistent. Objective-C APIs 
>> which return an error by reference using an autoreleasing NSError ** pointer 
>> are converted to use the Swift try/catch mechanism, presenting the returned 
>> error as an ErrorProtocol (which is actually an NSError). Similarly, Swift 
>> APIs using try/catch are presented to Objective-C as autoreleasing NSError 
>> ** pointers, and the ErrorProtocol-conforming error is converted to an 
>> NSError when it is called by Objective-C. However, when passing around error 
>> objects in any way other than these, the errors are not bridged. An 
>> Objective-C API that takes an NSError, such as NSApp’s -presentError: 
>> method, still leaves NSError as the type in the interface presented to 
>> Swift, as do the many asynchronous APIs in Cocoa that return an NSError as 
>> one of the arguments to a completion handler. Swift APIs that accept 
>> ErrorProtocols, on the other hand, are not presented to Objective-C at all, 
>> necessitating any such APIs also be declared to take NSErrors.
>> 
>> - To convert ErrorProtocols to NSErrors, Swift provides a bridging 
>> mechanism, invoked via “as NSError”, which wraps the error in a private 
>> NSError subclass class called _SwiftNativeNSError. This subclass can be cast 
>> back to the original error type, thus returning the original wrapped error. 
>> When a Swift API that is marked “throws” is called from Objective-C and then 
>> throws an error, the same bridging mechanism is invoked. However, this 
>> bridging is not very useful, since Cocoa tends to use NSError’s userInfo 
>> dictionary to present error information to the user, and ErrorProtocol 
>> contains no equivalent to the userInfo dictionary. The result of this is 
>> that when a Swift API throws an error, and this error is passed to Cocoa, 
>> the user tends to get a generic error message instead of something actually 
>> useful.
>> 
>> - The above problem means that a Swift developer must be very careful never 
>> to use “as NSError”, and to be sure to construct an NSError when throwing an 
>> error in an API that may be called from Objective-C, rather than simply 
>> throwing the error directly, or else the error will not be properly 
>> presented. If the developer makes a mistake here, it will not be known until 
>> runtime. I have personally wasted quite a bit of time trying to hunt down 
>> points in a complicated prog

Re: [swift-evolution] [Pitch] Reducing the bridging magic in dynamic casts

2016-05-09 Thread Charles Srstka via swift-evolution
> On May 6, 2016, at 2:04 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> The ugly NSError pattern could be rewritten and migrated to:
> 
> do {
>try something()
> } catch let error {
>handle(error `bridge` NSError)
> }
> 
> Is such a change complicated, what do you think?

I’ve made a pitch, "Consistent bridging for NSErrors at the language boundary”, 
which I believe would not only eliminate the need for “as” to contain bridging 
magic, but is also much less ugly than either the current pattern or the 
example above.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016618.html
 


Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0086: Drop NS Prefix in Swift Foundation

2016-05-09 Thread Charles Srstka via swift-evolution
I’m afraid I generally have to agree with this criticism. For types like NSURL 
which would make sense to become value types in the future, dropping the prefix 
does seem as if it would put constraints on future growth.

I do think the enum hoisting is great, though, and if it were in a separate 
proposal I’d definitely +1 it.

Charles

> On May 9, 2016, at 6:57 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>  • What is your evaluation of the proposal?
> 
> I support the enum hoisting and case renaming, but not the dropping of the 
> "NS" prefix quite this widely, for several reasons:
> 
> 1. I agree with the critique that "NSCoder" and its ilk should retain their 
> "NS" prefix because they represent something very specific to Foundation, not 
> some general concept of a "coder". ("JSONSerialization", on the other hand, 
> *is* something quite generic.)
> 
> 2. I think the "NS" prefixes may be a valuable indicator of which types are 
> values and which are references. (For this to be the case, we might need to 
> drop some NS prefixes from certain enums.)
> 
> 3. I am wholly unconvinced by the arguments in the "Keep NS on future value 
> types" section.
> 
> Another proposal (I'm behind, so I'm not sure if it's been accepted) suggests 
> that we add a value-typed `URL` to Foundation. Think about what would happen 
> if that proposal were deferred to Swift 4: `NSURL` would be renamed to `URL` 
> in Swift 3, and then Swift 4 would want to use `URL` for something else. At 
> that point, we have several choices, none of them very nice:
> 
> * Rename uses of `URL` back to `NSURL`, only one version after making the 
> opposite change. Note that this doesn't only mean migrating code, but also 
> developers' understanding of the frameworks—people will misread code for a 
> while.
> 
> * Choose a different name for the new value-typed `URL`, like `URLValue` or 
> `URI` or something. The preferred type then gets a suboptimal name.
> 
> * Deprecate the `URL` name, encourage use of `NSURL` instead, and delay the 
> introduction of the new `URL` for a version or two while the deprecation 
> works its magic. Now we've slowed down the evolution of the language.
> 
> Any of these seems like a huge own goal next to the alternative of simply 
> leaving all (or most) NS prefixes in place, at least until we feel the main 
> work of adding value types to Foundation is complete.
> 
>>  • Is the problem being addressed significant enough to warrant a change 
>> to Swift?
> 
> Sure, Foundation needs some cleanup. Just not *this* cleanup.
> 
>>  • Does this proposal fit well with the feel and direction of Swift?
> 
> Yes and no. I worry it'll slow the adoption of value types by Foundation, 
> which would not be a good thing.
> 
>>  • If you have used other languages or libraries with a similar feature, 
>> how do you feel that this proposal compares to those?
> 
> N/A.
> 
>>  • How much effort did you put into your review? A glance, a quick 
>> reading, or an in-depth study?
> 
> Quick reading, I suppose.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0086: Drop NS Prefix in Swift Foundation

2016-05-09 Thread Charles Srstka via swift-evolution
On May 9, 2016, at 7:38 PM, Rod Brown via swift-evolution 
 wrote:
> 
> I am uncertain about the NSCoding proposition as it is not a generic concept 
> that is platform agnostic. It is a baked in, Objective-C, Apple-only paradigm 
> that seems to me should retain it’s NS prefix.

Plus, NSCoding has a *lot* of legacy cruft associated with it that we would do 
well to jettison with a brand-new coding protocol, IMO.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Idea] Replace enumerate() with something more explicit

2016-04-15 Thread Charles Srstka via swift-evolution
> On Apr 15, 2016, at 8:09 PM, Andrew Bennett via swift-evolution 
>  wrote:
> 
> I'm in support of a method of getting a sequence of (Index,Value) pairs (as 
> you know from the other thread). I think I'm leaning toward option three if 
> it's equivalent to `zip(self.indices, self)`, ideally as a concise property 
> like keys/values on a Dictionary.
> 
> I've been using zip in production. I presumed enumerate was intended for 
> enumerating indices, and that it had just been forgotten when the slice 
> changes went through. I'm in favour of removing it.

Instead of removing it, how about just fixing it so that it returns the proper 
indexes rather than arbitrary numbers?

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0068: Expanding Swift Self to class members and value types

2016-04-20 Thread Charles Srstka via swift-evolution
* What is your evaluation of the proposal?

Mixed. I definitely think we need the functionality, but I think naming it 
“Self” may be confusing, since it means “self” and “Self” will mean two 
distinct things, despite varying only in the case of the first letter.

* Is the problem being addressed significant enough to warrant a change to 
Swift?

Definitely. As the proposal says, MyExtremelyLargeTypeName.staticMember is very 
unwieldy and awkward, and also fragile in case the type's name is changed.

* Does this proposal fit well with the feel and direction of Swift?

I feel that if given a name other than Self, it will be. As proposed, there is 
a potential for confusion between “self” and “Self”.

* If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?

Objective-C has [[self class] classMethod] but lacks type checking on it. This 
is an improvement.

* How much effort did you put into your review? A glance, a quick reading, or 
an in-depth study?

Read through the whole thing.

Charles

> On Apr 20, 2016, at 12:16 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0068: Expanding Swift Self to class members and value 
> types" begins now and runs through April 25. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Accepted] SE-0072: Fully eliminate implicit bridging conversions from Swift

2016-05-06 Thread Charles Srstka via swift-evolution
On the downside: This is absolutely true. All of those conversions would be the 
first up against the well when the revolution comes.

On the upside: I imagine a compiler warning could be pretty reasonably whipped 
up to detect these, and after the dust cleared, we’d be able to just try 
Int32(foo) and either the initializer would exist, or it wouldn’t, and it 
wouldn’t be necessary to bust out a playground and test to see if it’ll 
actually work every time you want to cast something to a number type that’s not 
your basic Int or Float.

Charles

> On May 6, 2016, at 11:01 PM, Jacob Bandes-Storch  wrote:
> 
> Agreed, but I'm sure lots of user code depends on it (e.g. when extracting 
> numeric values from property lists). If it stopped working, wouldn't these 
> "as?" casts silently start returning nil where they didn't before?

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Dropping NS Prefix in Foundation

2016-05-07 Thread Charles Srstka via swift-evolution
On May 6, 2016, at 5:06 PM, Tony Parker via swift-evolution 
 wrote:
> 
> Hi David,
> 
>> On May 6, 2016, at 2:56 PM, David Waite > > wrote:
>> 
>> -1 On the group as-is. I do not believe all of these classes have the 
>> behavior that would be expected if ‘foundation’ were a from-scratch 
>> foundational library for Swift (as it exists on non Apple platforms). This 
>> will lock Swift into an evolutionary path for these types going forward.
>> 
>> There is enough here that I will just pick one example to focus on - 
>> NSCoding/NSCoder, and elements I would suspect from such a from-scratch 
>> design
>> 
>> - Coding would incorporate SecureCoding into its design (I did not see 
>> NSSecureCoding even on the list of protocols to get the prefix dropped)
> 
> SecureCoding should be on the list actually.
> 
>> - Archiver/Unarchiver would not exist; we would only have keyed versions
>> - Coder would be a split in half to Coder and Decoder
>> - Coder and Decoder would be protocols
>> - The Coder protocol might have a single method, encode(value:Coding, 
>> forKey:String)
>> - The Decoder protocol might single method,  decode(type:T.Type, 
>> forKey: String) -> T?
>> - Compiler generation of a default Coding implementation
>> 
>> And possibly more such as:
>> - Add Coders limited to trees of objects vs graphs, to allow the 
>> Coder/Decoder protocols to be used for more intuitive JSON/XML 
>> representations
>> - Custom/specific assignment operator for Decoder to capture desired type 
>> without requiring said type to be specified in decode(type:forKey:) calls
>> 
>> -DW
> 
> There’s no question that we can improve Coding for Swift. I have actually 
> explored this area quite a bit although I don’t have anything planned for 
> Swift 3 at this time.
> 
> The general point is though, that we can do it by extending Foundation in 
> that direction over time. In fact, keyed archiving is the perfect example of 
> how we were able to do just that in the past in Objective-C. NSArchiver 
> already existed and served a particular purpose, so we extended the concept 
> into NSKeyedArchiver using the facilities available to us at the time.
> 
> It’s not a goal to rewrite Foundation from scratch in Swift. All Swift apps 
> that are running out there today are in fact using a combination of Swift, 
> Objective-C, C, C++, various flavors of assembly, and more. The goal is to 
> present the existing API of Foundation in a way that fits in with the 
> language today while allowing us to iteratively improve it over time.
> 
> - Tony

The trouble with (NS)Coding is that due to the legacy cruft, you have to 
consider the possibility that the coder sent to your -initWithCoder: and 
similar methods could be insecure coders and/or non-keyed coders, and either 
support each branch (making your method three times as long as it needs to be), 
or add code to error out if you get one of the legacy coder types.

A brand new coding mechanism, built from scratch, would be kind of refreshing 
in that regard.

Charles

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


  1   2   3   4   >