Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Gul Banana
Nov 28, 2003

failable initialisers are cool. sort of. i've often lamented the inability of constructors to fail and the factory patterns this creates.

that said, it feels like they're there for "the wrong reasons" - interoperability with old two-phase-construction apis.. but hey, if they can be wrapped sufficiently for the static analysis to be reliable, that's fine.

presumably this is another nail in the coffin of exceptions on the cocoa platform.

Adbot
ADBOT LOVES YOU

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

rjmccall posted:

Yes. Is that not true in Swift? If you've declared it somewhere, and exposed it to ObjC with @objc, that's worth a bug.

You know what I just re-tested it and it appears to, but it was not working in my real project. I may have some header madness screwing things up.


quote:

It's on the bucket list. Er, at least the list of possible values for payload-less enums is. Meaningfully enumerating payloaded enums would probably require static or dynamic metaprogramming; what's your goal?

Bridge swift enums to Objective-C so when I create entirely new functionality in Swift (that needs to be consumed by old ObjC classes), I don't have to drop back to ObjC just to define an old-fashioned NS_ENUM.

For basic raw enums with no functions that inherit from NSInteger or some other integral type obviously Swift could just emit the appropriate C-style enum even though it doesn't today, but I think it makes more sense to expose them as objects.

eg:

code:
@objc enum YouDontSay {
    case WellINever(String)
    case HowDareYou(Int, Int)
    func HitMe() { }
}
translates to:

code:
@interface YouDontSay : NSObject
+ (YouDontSay *)wellINeverWith:(NSString *)value1;
+ (YouDontSay *)howDareYouWith:(NSNumber *)value1 and:(NSNumber *)value2;
- (BOOL)isWellINeverInstance;
- (BOOL)isHowDareYouInstance;
@property (readonly, nonatomic) NSArray *values;
@end
So on the Objective-C side it may be ugly, but you can construct "boxed" enumeration values, get values out (by examining the array), determine which enum value you have, etc. Obviously you could design it a bit differently (subclasses for the different cases or something), but that's the general concept. If I had that kind of metaprogramming capability at runtime or compile time (ala Rust macros) it would be totally doable.

So that and @protocol circular header references are the two really annoying pain points right now. A class which needs to be included in my bridge header also needs to implement a protocol defined in swift. Oops, no-can-do buster! So I end up with Objective-C files that shadow half my Swift classes just to declare protocols and enumerations.


I also ran into this hilariousness:

code:
//ObjC code in some stupid VC somewhere
- (void)viewDidAppear:(BOOL)animated
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        MyViewController *vc = [[MyViewController alloc] initWithValues:@[@"yes", @"no", @"maybe"]];
        [self.navigationController pushViewController:vc animated:YES];
    });
}

//Fancy new swift VC
@objc class MyViewController : UIViewController {
    var someArray:[String]?
    required init(values:[String]) {
        self.someArray = values
        //cool, someArray has three values!
        println("someArray.count = \(someArray?.count)")
        super.init()
    }

    //Swift claims this is required, wtf?
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    //fun
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    
    //OOPS, someArray is nil!
    override func viewDidLoad() {
        println("someArray.count = \(someArray?.count)")
    }
}
That's right, the values set in the initializer are blown away after initialization is done. Guess what happens if someArray is not nillable? Crash!

I boiled it down to the simplest case and it appears that calling super.init() instead of super.init(nib,bundle) triggers the failure in initialization. If you call super.init() and don't implement override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) you get a nice crash concerning an unimplemented initializer.

OK you say, you're calling the wrong initializer for a view controller... Well smartypants, guess what happens if you inherit from UITableViewController and call super.init(style:UITableViewStyle) like a normal person? It behaves as if you had called super.init(), complete with crashes and missing values.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Gul Banana posted:

failable initialisers are cool. sort of. i've often lamented the inability of constructors to fail and the factory patterns this creates.

that said, it feels like they're there for "the wrong reasons" - interoperability with old two-phase-construction apis.. but hey, if they can be wrapped sufficiently for the static analysis to be reliable, that's fine.

presumably this is another nail in the coffin of exceptions on the cocoa platform.

Hmm. Initializers serve two sortof different purposes, depending on what they're initializing.

The first is what I would call "complete-object initialization". This is when you write Foo(widget: obj) or whatever. To the extent that this is kindof just like a function call that usually returns a new object, it makes sense that it can fail. There's no problem here.

The second is what I would call "base-subobject initialization". This is when you're in a subclass's initializer and you write super.init(widget: obj). It's a lot more problematic for this to fail, because it's very intricately tied into the initialization of the object. In a world where initialization sets up useful invariants on objects (most primitively that all fields have been validly initialized, but of course you can have higher-level invariants), but where we also don't want to impose weird restrictions on what methods you can call in initializers (or make such methods behave totally differently at that time, like they do in C++), we have to be really picky about how and when you can fail. And I think that that pickiness reflects a real issue in Objective-C, which is that failing superclass initializers leave the allocated object in a really precarious state that you have to be very careful to program around; e.g. if you want to write a dealloc method on a class with a failable initializer you had better understand what exactly is going to happen when that initializer fails, because you are probably not prepared for it, and your object is not going to be in any kind of consistent state anymore. And even getting that far relies on assumptions about initialization and object invariants that are just deeply problematic.

But we're in a difficult position, because there do exist failable designated initializers in Objective-C, and they do pose all these issues, and that makes it really difficult to formalize behavior around them. And the idea of complete-object initialization being able to fail is still really interesting, and it lures people towards these perilous jagged rocks that we don't know how to dissuade them from. So I expect it'll take a lot more iteration, which is terrifying because of how much effort it's taken to even get this far. Object models are hard.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

Bridge swift enums to Objective-C so when I create entirely new functionality in Swift (that needs to be consumed by old ObjC classes), I don't have to drop back to ObjC just to define an old-fashioned NS_ENUM.

For basic raw enums with no functions that inherit from NSInteger or some other integral type obviously Swift could just emit the appropriate C-style enum even though it doesn't today, but I think it makes more sense to expose them as objects.

That is a really interesting idea, and I have no idea what to tell you. Metaprogramming, I guess.

Ender.uNF posted:

That's right, the values set in the initializer are blown away after initialization is done. Guess what happens if someArray is not nillable? Crash!

Yeah, so the issue here is that init() is not the designated initializer for UIViewController, and that hasn't been marked in the headers, so we have to be conservative and assume you know what you're doing. Don't super-delegate to a non-designated initializer.

Ender.uNF posted:

OK you say, you're calling the wrong initializer for a view controller... Well smartypants, guess what happens if you inherit from UITableViewController and call super.init(style:UITableViewStyle) like a normal person? It behaves as if you had called super.init(), complete with crashes and missing values.

Ugh. This is so screwed up. The problem is that initWithStyle: does not behave like a designated initializer for UITableViewController, because it doesn't call a designated initializer from its superclass: it calls init, which on UIViewController is a convenience initializer which re-dispatches down to the most-derived class's initWithNibName:bundle:. So, basically, initWithStyle: is not a designated initializer, and when you're super-delegating, you need to be calling the designated initializer, which is initWithNibName:bundle:. I'm sorry this isn't (1) documented and (2) properly annotated in the header.

chaosbreather
Dec 9, 2001

Wry and wise,
but also very sexual.

cowtown posted:

Am I missing something, or is this just a lexer/parser and nothing else?

Hey now they're also kickstarting their own smartphone, it's a lot of work to design a whole phone while maintaining your indie cred.

feedmegin
Jul 30, 2008

chaosbreather posted:

Hey now they're also kickstarting their own smartphone, it's a lot of work to design a whole phone while maintaining your indie cred.

Their 'team' appears not to contain any programmers. Or hardware guys. But 3 designers. :shobon:

Stoph
Mar 19, 2006

Give a hug - save a life.

feedmegin posted:

Their 'team' appears not to contain any programmers. Or hardware guys. But 3 designers. :shobon:

This is taking this thread way off topic but these guys are building their own open-source version of Swift, AND a distributed social network, AND their own open-source operating system...

quote:

With Project Stratosphere, we are building the Indienet.

The first steps are Heartbeat — a beautiful, distributed social network client — and Indie OS — an operating system.

But we can’t stop there.

When Google and Apple create beautiful experiences, they control the hardware, the operating system, and the core services. The combination of these three components comprises the user experience. Without control over all three, you do not have control over the end-user experience and cannot possibly hope to compete on experience.

Which is why we are designing a phone.

We want Indie Phone to be the most beautiful way to experience the Indienet.

But now they're also hardware manufacturers AND mobile application developers? :iiam:

brap
Aug 23, 2004

Grimey Drawer
So I'm serializing some JSON into a dictionary. It seems like the ordering is not being completely honored and I just can't guess why. My inputs to the REST API look like "11776,11880,13220". Sending a request to the endpoint in my browser gets me a dictionary with the keys written in this order.

Enumerating the keys in the JSON dictionary that comes back from NSJSONSerialization gets me these values: "11776,13220,11880"

Is it normal to see this behavior? Is there any reason it happens to be in this order as opposed to any other?

dizzywhip
Dec 23, 2005

Dictionaries are inherently unordered, if you need values in a specific order you have to use an array.

brap
Aug 23, 2004

Grimey Drawer
Yeah, just strange that it's in a consistent but wrong order. I'm mostly irritated with the guys designing the API as there isn't much reason for it to be a dictionary as opposed to an array.

dizzywhip
Dec 23, 2005

I'm not sure what exactly determines the order that you get entries back when enumerating a Swift or NSDictionary, but it doesn't surprise me too much that it appears to be consistent under the same circumstances. You just can't rely on it always being that way. If you don't have control over the format you get the data in, you'll have to process the values into an array and sort it yourself.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Building a hash table is a deterministic process unless your hash function uses raw pointer values or something. (And even that is only non-deterministic if something about your system makes it so — e.g. if the dynamic linker uses ASLR, or if malloc starts at a different base address in every process, or something else along those lines.) And iterating it will typically just visit buckets in order, so iterating it multiple times will result in the same sequence unless you change the structure of the table in between, e.g. by adding enough entries to force the table to grow.

Of course, none of that is guaranteed, but that's why it happens to work out that way.

ETA: Mmm, I just remembered that there are hashtable implementations that do incorporate a random, table-specific value whenever creating a new hashtable. That serves several purposes: one, like ASLR, it makes the hashtable harder to exploit; two, it makes the instability of iteration much more obvious, reducing the odds that somebody accidentally relies on it; and three, it can make help protect against weak hash functions, depending on how you incorporate the seed. But I don't think NSDictionary or Swift.Dictionary do this.

rjmccall fucked around with this message at 00:16 on Oct 23, 2014

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

rjmccall posted:

That is a really interesting idea, and I have no idea what to tell you. Metaprogramming, I guess.


Yeah, so the issue here is that init() is not the designated initializer for UIViewController, and that hasn't been marked in the headers, so we have to be conservative and assume you know what you're doing. Don't super-delegate to a non-designated initializer.


Ugh. This is so screwed up. The problem is that initWithStyle: does not behave like a designated initializer for UITableViewController, because it doesn't call a designated initializer from its superclass: it calls init, which on UIViewController is a convenience initializer which re-dispatches down to the most-derived class's initWithNibName:bundle:. So, basically, initWithStyle: is not a designated initializer, and when you're super-delegating, you need to be calling the designated initializer, which is initWithNibName:bundle:. I'm sorry this isn't (1) documented and (2) properly annotated in the header.

You can't directly set the style so there is no possibility of calling some other initializer. That makes it impossible to have a UITableViewContoller-derived subclass in swift with an initializer... unless you're banning grouped table views :v:

rdar://18747436

Simulated fucked around with this message at 08:28 on Oct 23, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Ender.uNF posted:

You can't directly set the style so there is no possibility of calling some other initializer. That makes it impossible to have a UITableViewContoller-derived subclass in swift with an initializer... unless you're banning grouped table views :v:

rdar://18747436

Wow, that is really terrible. Trying to escalate.

brap
Aug 23, 2004

Grimey Drawer
"All stored properties of a class instance must be initialized before returning nil from an initializer."

What is the point of this? Why can't I return nil at ANY point during initialization?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

fleshweasel posted:

"All stored properties of a class instance must be initialized before returning nil from an initializer."

What is the point of this? Why can't I return nil at ANY point during initialization?

My guess is so that the deinitializer can be called cleanly.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

pokeyman posted:

My guess is so that the deinitializer can be called cleanly.

Yep. I think we'd like to loosen this restriction over time, but we'd need to figure out the exact interplay with subclass initializers. This is complicated enough in a pure-Swift world, but the requirement for ObjC interop makes it really difficult.

So here's the problem. A complete object is a collection of base-class subobjects, and it's fully constructed if all of the properties in all of those subobjects have been assigned. ObjC subobjects are fully constructed during allocation, not initialization; this works because we assume that zero-initialization is good enough for C/ObjC types, and C++ class types are required to provide a default constructor. That doesn't work in Swift, mostly because we have types that we aren't willing to give reasonable default states to; non-optional class references are the most obvious example. From a single Swift class's perspective, it's fully constructed after the super.init call returns successfully or (if in a root class) after you've assigned all the properties; this works because Swift initializes properties "on the way down".

You can't safely destroy an object until it's been fully constructed, which is why Swift prevents arbitrary uses of self until that point. Once an object is fully constructed, you have to assume that there might be arbitrary references to it (set up, for example, by the superclass's initializer), so the only reasonable thing that we can do if an initializer fails at this point is release self and return. But if you want to fail before the object is fully constructed, that doesn't work; you definitely can't call deinit(), which is allowed to use "self" in unrestricted ways, but even "primitive" deinitialization may try to destroy properties which are still uninitialized. So you have to be able to unwind initialization, including up through subclasses, and delay deallocation until you've unwound all the way up. And I think it's possible to make that interact sensibly with the ObjC initialization protocol, including both ObjC superclasses and ObjC subclasses, but it's definitely tricky.

dizzywhip
Dec 23, 2005

This was in my dream last night

Toady
Jan 12, 2009

My waking nightmare.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
code:
// Playground - noun: a place where people can play
import Cocoa

@objc class HiHo : NSObject { }
@objc class OffToWorkWeGo : HiHo { }
func OkilyDokily() -> OffToWorkWeGo? { return nil }
func Wat() -> (OffToWorkWeGo?, NSError?) { return (nil, nil) }

var wat:HiHo?
var err:NSError?

wat = OkilyDokily() //okily-dokily!

(wat, err) = Wat() //Cannot express tuple conversion, you jerk
Totally safe upcast? That's cool.

Oh wait, in a tuple? gently caress right off. rdar://18792507

Also confirmed rdar://18747436 is still alive and well in 6.1.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
Today's random bug rdar://18807413 AKA "7 is a magic number":

code:
let v1:String? = nil
let v2:String? = nil
let v3:String? = nil
let v4:String? = nil
let v5:String? = nil
let v6:String? = nil
let v7:String? = nil
let v8:String? = nil
let v9:String? = nil

if let x = v1 ?? v2 ?? v3 ?? v4 ?? v5 ?? v6 ?? v7 ?? v8 ?? v9  { }
With 6, performance gets very slow. With 7, it takes a minute to execute. At 9, my laptop turned into a space heater.


Trying to do serialization/deserialization has me very nearly tossing this Swift code out and doing it in Objective-C. There's probably a better way that I just can't see right now, but so far its just a lot of manual ["key" : self.key] crap everywhere, and the inverse on the other side. I was trying to coalesce all the json-swift JSValue.errors to see if any errors are present. It was working great up until I hit a larger class.

The funny part is in C# I would just use the JSON serializer and literally be done in five minutes; it would automatically map read/write properties bidirectionally, handle arrays/dictionaries, nested values, etc.

dizzywhip
Dec 23, 2005

I posted this earlier in the thread, but I wrote a little JSON handler that might be helpful for you: https://gist.github.com/dizzywhip/046691faa20ef5a1b0db

It's still a little more cumbersome than using JSON in Objective-C or C# when you're reading data due to the type safety, but I actually like it a lot because it kind of forces you to properly handle unexpected data.

brap
Aug 23, 2004

Grimey Drawer
I'm having trouble implementing the MKMapViewDelegate viewForAnnotation method. Conventional wisdom seems to suggest that the body of this method needs to return a nil for the user location annotation to get the proper appearance for it, like so:

let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("MKAnnotationView") ?? MKAnnotationView()
if annotationView is MKUserLocation {
return nil
}

This fails to compile with the error "MKUserLocation is not a subtype of MKAnnotationView." The legacy way of doing it with Swift syntax appears to be: annotationView.isKindOfClass(MKUserLocation). That compiles, but doesn't give the default appearance for the location dot. Am I screwed on writing this in Swift? Is it time to bust out the Objective-C for my map view delegate?

edit: annotationView.annotation.title == "Current Location" works, but it smells. :getin:

edit again: Finally realized that MKUserLocation is an MKAnnotation, not an MKAnnotationView.

brap fucked around with this message at 18:04 on Nov 1, 2014

bolind
Jun 19, 2005



Pillbug
Can I just say that this language is making me more excited about programming that I've been for years.

I work in an embedded world, where everything is C, because of ~speed!~ and ~embedded!~, but for fucks sake, 80% of what we do is managing a dozen state machines, sending messages and events around, and receiving button presses and making LEDs blink in one of two colors. I'd love for all this to be written in a safe, practical, concise language.

lord funk
Feb 16, 2004

Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same.

Kallikrates
Jul 7, 2002
Pro Lurker
I've been favoring not using self unless for whatever reason it's required. Which right now is closures, or cases where a variable shadows something in a different scope. Hope to hear some others respond.

Edit: I feel like no best practices are developing because no one wants to be wrong when language changes break previous assumptions.

Kallikrates fucked around with this message at 16:25 on Nov 3, 2014

geera
May 20, 2003

lord funk posted:

Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same.
I've just been using the property name without 'self' because it's less typing. But if I were on a team or writing code for public release I would probably use 'self' for clarity.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

lord funk posted:

Not sure if this is a style question or not. Is there any functional difference between referring to properties with self.property vs. just property? I use the former because I think it clarifies that it's a class property and not just a local variable, but I'm wondering if others are doing the same.

It is a style question, and I don't think you meant "class properties". Anyway I do what I do for ivars in Objective-C: skip the self unless it's needed because of shadowing. I feel like I have even more of a leg to stand on for this in Swift, what with all the type inferencing. Though if you put an underscore in your ivar names that works well as a sigil. In conclusion, Libya is a land of contrast.

Morroque
Mar 6, 2013
I'm somewhat embarassed to admit it, but I never quite got a good handle on using the Interface Builder -- the old Objective C tutorial book I had wanted to do things the hard by hard-coding everything by setting CGRects and all, but I couldn't get very far with it and the result of that meant I just only ended up with a rather nebulous idea of how View Controllers and everything even worked.

I need to pick up making GUIs in iOS pretty quickly now, but the majority of the tutorials I find are still Objective C oriented. Is the Interface Builder for Swift any different?

brap
Aug 23, 2004

Grimey Drawer
Interface Builder is not particularly related to Objective-C or Swift except that you can create outlets to UI elements defined in IB or target actions in your view controller.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Morroque posted:

I'm somewhat embarassed to admit it, but I never quite got a good handle on using the Interface Builder -- the old Objective C tutorial book I had wanted to do things the hard by hard-coding everything by setting CGRects and all, but I couldn't get very far with it and the result of that meant I just only ended up with a rather nebulous idea of how View Controllers and everything even worked.

I need to pick up making GUIs in iOS pretty quickly now, but the majority of the tutorials I find are still Objective C oriented. Is the Interface Builder for Swift any different?

Nah it's pretty much identical. Instead of IBAction you use @IBAction. Little stuff like that.

brap
Aug 23, 2004

Grimey Drawer
How do I write an extension method that is nil-safe (i.e. can be invoked on an optional)?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

fleshweasel posted:

How do I write an extension method that is nil-safe (i.e. can be invoked on an optional)?

If you mean that you specifically want to extend SomeType?, the answer is that you would write extension SomeType? — but don't bother, that's not supported (yet). Otherwise, you can make it a global function.

I'm skeptical that making a "nil-safe" method in that sense is actually a good idea, though.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

rjmccall posted:

If you mean that you specifically want to extend SomeType?, the answer is that you would write extension SomeType? — but don't bother, that's not supported (yet). Otherwise, you can make it a global function.

I'm skeptical that making a "nil-safe" method in that sense is actually a good idea, though.

I've written something like
code:
if empty(maybeString) {
  // ...
}

func empty(s: String?) -> Bool {
  if let s = s {
    return s.isEmpty
  }
  return true
}
a few times, whereas in Objective-C I'd have taken advantage of messaging nil and written
Objective-C code:
if (maybeString.length == 0)
  // ...
(I'm not presenting this as a particularly compelling use case, mind you, but it's one I've stumbled into.)

brap
Aug 23, 2004

Grimey Drawer
The reason is simply that it allows for chaining and reduction of nil checks.

code:
if let foo = object.optionalProperty?.child.methodWhichReturnsAnOptional() {
}
as opposed to

code:
if let foo = object.optionalProperty {
    if let bar = foo.child.methodWhichReturnsAnOptional() {
    }
}
Although I maybe am not expressing the exact situation where an extension on an optional would be useful, I think you can see where it would be. Equivalents to .NET's string.IsNullOrEmpty() and IEnumerable.any() would probably be really common.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

fleshweasel posted:

The reason is simply that it allows for chaining and reduction of nil checks.

code:
if let foo = object.optionalProperty?.child.methodWhichReturnsAnOptional() {
}
as opposed to

code:
if let foo = object.optionalProperty {
    if let bar = foo.child.methodWhichReturnsAnOptional() {
    }
}
Although I maybe am not expressing the exact situation where an extension on an optional would be useful, I think you can see where it would be. Equivalents to .NET's string.IsNullOrEmpty() and IEnumerable.any() would probably be really common.

Not that I disagree - I too have run into situations where extending SomeType? would be useful - but you can already chain optional method invocations that way.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
I'm finding myself wanting to use tuples as multi-part dictionary keys from time to time because of how easy they are to construct syntactically (imagine a table mapping something like (KeyboardAppearance, ControlState) to UIColors). I hate the extra effort of defining a full struct for this *and* the hash/equality methods.

Would it be possible for the language to make a tuple type conform to Hashable/Equatable if all of the types of their elements conform to Hashable/Equatable?

Flobbster fucked around with this message at 16:05 on Nov 11, 2014

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's a future direction that we want to pursue when, y'know, we have a more stable base for the existing language. It's easy to do if we want to hardcode tuples and Hashable/Equatable; it requires a lot more infrastructure to make a general feature, mostly because tuples are variadically generic.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"
I'm always happy to wait for a well-designed general feature than a specific hack :) I'm really looking forward to what Swift brings to the table w.r.t. generics overall. From what I've already seen in the standard library and what you've talked about wanting to do, I'm hoping that we're going to start getting a lot closer to the power of C++ templates than a lot of other modern languages since then (at least as close as you can get without doing the same substitution-only approach used there).

On that note, I was recently trying to write a generic matrix ADT that would have a fixed size at initialization time, but when I tried to fill the array using the (count:repeatedValue:) initializer, I hit a stumbling block:

code:
class Matrix<T> {
    private let values: [T]

    init(rows: Int, cols: Int) {
        values = [T](count: rows * cols, repeatedValue: T())
    }
}
This obviously fails because there isn't enough information about T to know that it can be parameterlessly-initialized, and a protocol constraint wouldn't help here. Do you have thoughts about this (something similar to concepts?) in your future roadmap?

Adbot
ADBOT LOVES YOU

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Flobbster posted:

I'm always happy to wait for a well-designed general feature than a specific hack :) I'm really looking forward to what Swift brings to the table w.r.t. generics overall. From what I've already seen in the standard library and what you've talked about wanting to do, I'm hoping that we're going to start getting a lot closer to the power of C++ templates than a lot of other modern languages since then (at least as close as you can get without doing the same substitution-only approach used there).

On that note, I was recently trying to write a generic matrix ADT that would have a fixed size at initialization time, but when I tried to fill the array using the (count:repeatedValue:) initializer, I hit a stumbling block:

code:
class Matrix<T> {
    private let values: [T]

    init(rows: Int, cols: Int) {
        values = [T](count: rows * cols, repeatedValue: T())
    }
}
This obviously fails because there isn't enough information about T to know that it can be parameterlessly-initialized, and a protocol constraint wouldn't help here. Do you have thoughts about this (something similar to concepts?) in your future roadmap?


This is equivalent to the "new" constraint in C# and I second the motion.

Also big news: very shortly we will be shipping our first Swift code. Other than a few pain points the overall experience makes writing Objective-C seem like COBOL already.

  • Locked thread