|
Is it possible to store an array of class types? I have a group of classes that conform to a protocol which declares a static variable.code:
code:
|
# ? Jun 16, 2015 14:59 |
|
|
# ? May 14, 2024 21:53 |
|
The more Swift we do, the less and less I'm willing to allow force unwraps to make it through code reviews. Is that completely misguided or is having lots of if lets what we do with Swift?
|
# ? Jun 16, 2015 15:09 |
|
lord funk posted:Is it possible to store an array of class types? I have a group of classes that conform to a protocol which declares a static variable. Does let classes = [Foo.self, Bar.self] work? Doh004 posted:The more Swift we do, the less and less I'm willing to allow force unwraps to make it through code reviews. Is that completely misguided or is having lots of if lets what we do with Swift? Use them where crashing is reasonable behaviour. The file manager can't give you back your App Support path? You're hosed, crash it. You're pretty sure this array is nonempty but you can't be arsed to check? Try harder.
|
# ? Jun 16, 2015 15:19 |
|
pokeyman posted:Does let classes = [Foo.self, Bar.self] work? Yes! Requires Swift 2 to access the properties, but it works: code:
|
# ? Jun 16, 2015 15:41 |
|
Doh004 posted:The more Swift we do, the less and less I'm willing to allow force unwraps to make it through code reviews. Is that completely misguided or is having lots of if lets what we do with Swift? Our Style guide heavily discourages any force un wrapping. The nil check needs to be a short distance from the call to the force for me to allow it. But there is no blanket "Never do it ever". code:
|
# ? Jun 16, 2015 16:21 |
|
Basically what pokeyman said. There are some calls that should crash your app if they return nil. For instance, I have in my app an NSURL instance created using a string literal. The only reason its initializer should fail is I wrote a bad URL string in my source code. Instead of my app sitting there and doing nothing, it might as well crash and let the debugger break on wherever the bad optional unwrap occurred. Crashes like that definitely shouldn't make it into release versions obviously. Once we get guard let, it will be a lot easier to eliminate most of the remaining instances of force unwraps. Kallikrates, I suspect a lot of people will be using an extension method like that one. I implemented it like this: code:
brap fucked around with this message at 16:42 on Jun 16, 2015 |
# ? Jun 16, 2015 16:37 |
|
I'm playing around with protocol extensions in Swift 2, and I'm hitting an interesting limitation. I have an inheritance hierarchy with a common base class which is a container for some values, and I'd like to replace it with a protocol. The problem is that if I extend the protocol with implementations of its methods (some of which are mutating), then I must declare the underlying container as settable in the protocol. This forces the type that publicly conforms to that protocol to also make its underlying container publicly mutable, even though I only want external code to mutate the container using the protocol methods. Here's a simplified example: code:
|
# ? Jun 17, 2015 05:09 |
|
It makes sense your protocol would need to expose a setter on the property in order to have an extension method mutate that property. You should put your add method signature in the protocol and implement it in your types conforming to the protocol. It feels like what you were hoping for was more like an abstract class in C#.
|
# ? Jun 17, 2015 06:10 |
|
Maybe you should do this with composition?
|
# ? Jun 17, 2015 06:43 |
|
Am I missing something here?Swift code:
pre:Cannot invoke 'max' with an argument list of type '(CGFloat, CGFloat)' EDIT 2: I didn't want to rename the variables, so I fixed it by using Swift.min and Swift.max to refer to the global functions. Sweet. Doctor w-rw-rw- fucked around with this message at 00:03 on Jun 18, 2015 |
# ? Jun 17, 2015 23:46 |
|
I totally love the way that Swift handles errors, but how come the 'throws' keyword comes between the parameters and return type? Its just 'myFailingFunction() throws -> Int { ... }' reads a bit like the function throws an Int...but I guess it makes sense as throwing an exception is sort of a possible return type..
|
# ? Jun 18, 2015 08:45 |
|
rjmccall posted:Maybe you should do this with composition? Yeah, I think this is probably the way to go in this case.
|
# ? Jun 18, 2015 16:04 |
|
toiletbrush posted:how come the 'throws' keyword comes between the parameters and return type? It's good for readability to be able to answer "what does this produce" in a single glance instead of having to search out two different places. You'll almost always want to know that a function can throw when you're looking for its return type. It has to go before the arrow because the arrow isn't always there, e.g. in initializers and functions returning ().
|
# ? Jun 18, 2015 18:02 |
|
Can you access a protocol's static variable in a protocol extension method?code:
|
# ? Jun 18, 2015 18:24 |
|
Just checking in to say that swift 2.0 protocols solve pretty much every complaint I had about them. Core Data is so so so much better now that I can have all my entity objects conform to a protocol which allows them to return properly typed arrays with barely any additional code per class. Self constraints are so good.
|
# ? Jun 18, 2015 20:14 |
|
lord funk posted:Can you access a protocol's static variable in a protocol extension method? Swift code:
|
# ? Jun 19, 2015 01:23 |
|
I love being able to return Self from methods on a class, it makes writing fluent interfaces that also involve inheritance beautiful. (Although now I'm wondering if I should be doing them with protocol inheritance, structs, and protocol extensions to provide the shared parts of the implementations.) Are there plans to expand support to Self can be used as part of a larger returned type expression? I ran into a situation where I wanted to write something like func foo() -> Helper<Self>, but that's not allowed.
|
# ? Jun 19, 2015 01:41 |
|
Not really; it's hard to reason about the dynamic type in arbitrary positions like that. Not impossible, but it would take some major work to do well.
|
# ? Jun 19, 2015 02:30 |
|
So I've decided to get back into Swift since I've got some time on my hands. Maybe this eluded me the first time around but is there no way to tag methods (for classes) as non-mutating to the instance's state? Basically I'm trying to understand if there exists a mechanism similar to C++'s "const".
|
# ? Jun 19, 2015 07:28 |
|
If you use structs instead of classes, then you get what you want the opposite way: all methods are "const" (non-mutating) unless you specify the mutating keyword. This won't help if you're forced to use classes, though (e.g., if you're inheriting from a framework class).
|
# ? Jun 19, 2015 07:49 |
|
Flobbster posted:If you use structs instead of classes, then you get what you want the opposite way: all methods are "const" (non-mutating) unless you specify the mutating keyword. This won't help if you're forced to use classes, though (e.g., if you're inheriting from a framework class). Thanks for the reply! I was aware of that but obviously structs have other tradeoffs. It would be interesting to hear the motivation behind such a design choice (paging rjmccall). e: "defer" is the most beautiful language feature I have ever seen in my entire life. shodanjr_gr fucked around with this message at 08:35 on Jun 19, 2015 |
# ? Jun 19, 2015 07:53 |
|
Mutability tracking in reference types is a lot more complex, and it's basically a different problem. The first thing to realize is that a const reference doesn't really say anything about the object; it's just a statement about what can be achieved through that particular reference. And it's a mostly orthogonal statement to the mutating notion for value types, because you can have either a variable or a constant holding either a const or a non-const reference. In particular, a non-mutating protocol requirement can be implemented with self-mutating class method, because the class method does not reseat the reference, because that's not how class methods work. So that's confusing. Okay. So you have a class, and now there are two different types of reference to it. If the default reference is const, you're going to force users to add a ton of pedantic non-const annotations, because the interface to many classes is centered around mutation. If the default reference is non-const, you have a major annotation propagation problem, because people will naturally write functions to expect non-const references even if they don't need to actually mutate; this means that you'll be running into incorrect annotations every time you try to lock down in one place, so that you're either endlessly janitoring const or relying on some const_cast-like explicit hole in the tracking. None of these choices are appealing. There are also big, awkward questions about how const/non-const references interact with stuff with protocol types, or dynamic casts, or just generics in general. And none of this actually gives you any guarantee in a non-mutating class method that you won't do something that causes a mutation through an aliasing non-const reference, so the benefits for reasoning about mutation are pretty weak.
|
# ? Jun 19, 2015 10:23 |
|
shodanjr_gr posted:e: "defer" is the most beautiful language feature I have ever seen in my entire life. Seriously. Such an elegant solution to the problem.
|
# ? Jun 19, 2015 21:47 |
|
Dessert Rose posted:Seriously. Such an elegant solution to the problem. Indeed! And from messing around in Playgrounds, it seems that you can have multiple of them within a scope and they get executed in sequence when you bail out. Which makes them even more awesome. I really appreciate the very detailed response and I can understand that properly enforcing const-correctness imposes some (non-trivial) overhead to developers which leads a lot of folks to cut corners and/or not do it right. So from what I gather, the only way (currently) for the compiler to enforce non-mutation is to use structs and "eat" the value-type overhead?
|
# ? Jun 19, 2015 22:50 |
|
Yeah, although I'm pretty sure copy on write makes it much less of a cost than you'd think for immutable structures.
|
# ? Jun 19, 2015 22:52 |
|
Yeah, there aren't any copies until its necessary. e: Re this, these WWDC sessions were really good imo: Building Better Apps with Value Types in Swift https://developer.apple.com/videos/wwdc/2015/?id=414 Protocol-Oriented Programming in Swift https://developer.apple.com/videos/wwdc/2015/?id=408
|
# ? Jun 20, 2015 00:57 |
|
will rethrows be the story for GCD async?
|
# ? Jun 20, 2015 09:10 |
|
rethrows as currently defined doesn't help a whole lot with async, because right now async is kindof a callback-hell situation, and it really needs a more holistic solution. You could make a very good wrapper for dispatch_sync that actually returned a result back, though, and also used rethrows.
|
# ? Jun 20, 2015 10:42 |
|
rjmccall posted:
I swear I tried this. =/ Maybe I just let it autocomplete to self. Ahh.
|
# ? Jun 20, 2015 16:16 |
|
I am absolutely amazed at Swift's progress as I read the new iBook and this thread. Really makes me want to make an iOS app in my spare time just to learn the intricacies. One general question: Do any of us think (or maybe know) if Swift is ever going to bake Regular Expression literals into the main library? I know the current solution is to use NSRegularExpression or rangeOfString, but boy does that feel janky and archaic compared to other languages. I may be an edge case, but 90% of the stuff I work on involves using regular expressions to deal with user text and convert it into something else.
|
# ? Jun 20, 2015 18:36 |
|
If nothing else I would like to see the API improved. NSRegularExpression seems a little bit clunky to me.
|
# ? Jun 20, 2015 20:22 |
|
rjmccall posted:rethrows as currently defined doesn't help a whole lot with async, because right now async is kindof a callback-hell situation, and it really needs a more holistic solution. maybe some kind of Future-ish type which encapsulated throws-ness in the same way as rethrows, so that it became a throws operation to get the ultimate result once something in the chain was given a throws closure... actually, is that possible as a library using overload-on-throwsness?
|
# ? Jun 20, 2015 20:24 |
|
fleshweasel posted:If nothing else I would like to see the API improved. NSRegularExpression seems a little bit clunky to me. Improved how? I don't expect NSRegularExpression to have all that much flexibility, since NSDataDetector derives from it and afaik it's used in a ton of text code.
|
# ? Jun 20, 2015 20:55 |
|
Gul Banana posted:maybe some kind of Future-ish type which encapsulated throws-ness in the same way as rethrows, so that it became a throws operation to get the ultimate result once something in the chain was given a throws closure... Yes. It's just a question of API design, i.e. whether you're willing to split the future type in two. Or you could have a future that produces a Result<T>, or whatever we end up calling it.
|
# ? Jun 20, 2015 21:28 |
|
Swift 1.2 1. Not sure how to create a string with an NSRange without using NSString. NSRange can't be converted easily to Swift's Range<String.Index>. 2. The option named "allZeros" throws me off until I think about the way options are often implemented with bitwise OR. I shouldn't even have to use an overload that takes options unless I need to stray from the defaults. 3. Why are there options at the time I create the regex instance and again at the time I perform a match? Do people normally write a pattern and then want to change the rules around during their parsing job? 4. Why do I have to provide an NSRange when by default it should be assumed I want to look for matches in the entire string? code:
code:
Also, I am looking forward to when pressing "." in a place where an enum function parameter belongs brings up the list of cases for that enum. Otherwise I have to type out the full name of the enum type while I'm just learning to use that particular enum. brap fucked around with this message at 21:40 on Jun 20, 2015 |
# ? Jun 20, 2015 21:35 |
|
rjmccall posted:(snip) rjmccall posted:Yes. It's just a question of API design, i.e. whether you're willing to split the future type in two. Or you could have a future that produces a Result<T>, or whatever we end up calling it. IMO Promise or Future style APIs are easy to abuse really, really badly. In one of my previous projects, a coworker wrote chains of promises with multiple branches which statefully changed a view controller (for example, showing/hiding the loading UI). It was a huge mess, and naturally, everything was crashy and hard to reason about. My takeaway was that without one of: a very strong convention of purity (mutating only locally within the code block), an in-language facility to help enforce purity, or a great deal of discipline, Futures and Promises seem to have a high risk of codebase devastation. I also think that they tend to be a poor fit for implementing frequent or complex UI mutations. I wrote a channel/pipeline framework very (very) loosely resembling Netty's and an application on top of it, and came away from it feeling that overall, it's just really hard to beat just writing code sequentially. Being able to do so and also punt control to the background for long-running tasks and pick up where you left off would be really good. That said, pausing the main thread and resuming it isn't exactly an option since UIKit requires the main thread to be continually running and minimally blocked for decent performance. tl;dr: What would adding a async/await abstraction to the language would look like? Would it have a clearer story for exception handling? I don't pretend to know how much of a pain in the rear end that would be to implement. Maybe some way to make a continuation passing style not look awkward as hell instead?
|
# ? Jun 20, 2015 22:57 |
|
fleshweasel posted:/big list of things unpleasant about using Regular Expressions in Cocoa/g Yes! Exactly. Thanks for writing that out. I can see why it might be a weird fit for the Cocoa libraries for Swift to have its own special regular expression functionality that operates differently from NSRegularExpression, but the current system feels like a ton of boilerplate weirdness just to accomplish simple tasks. Even having to write out regular expressions with double slashes (e.g. writing \d as \\d so NSString doesn't freak out) stands my hair on end. RegExes are ugly enough without extra slashes. The transition to Swift seems like an excellent opportunity to simplify things.
|
# ? Jun 21, 2015 03:39 |
|
IMO, a literal for raw strings (like with Python) that uses different escaping rules would be preferable to integrated regex functionality.
|
# ? Jun 21, 2015 04:43 |
|
After watching the great Protocol-Oriented Programming WWDC Swift talk and doing my first mediumly-complex iOS app with Swift 2, it's hard not be struck by how foreign the standard Cocoa/UIKit OO delegate/subclass OO stuff feels. It really makes me wonder what a completely Swift API development stack would be like. Pretty great, I bet.
|
# ? Jun 22, 2015 05:24 |
|
|
# ? May 14, 2024 21:53 |
|
rjmccall posted:Result<T>, or whatever we end up calling it. Burrito<T>
|
# ? Jun 22, 2015 05:49 |