4 ms·
Actually, some of those features are still buggy when operating to Obj-C land :) //Warning if you don't use let :-) let array = NSMutableArray(ca
by seivan 11y ago
Actually, some of those features are still buggy when operating to Obj-C land :)
//Warning if you don't use let :-)
let array = NSMutableArray(capacity: 50)
array.addObject(notification)
I am aware that the let essentially means I can't reassign the variable, and does not have anything to do with the mutability of the class. Since it's a class and not a struct.
However, what I am saying is that Apple needs to somehow add the keywords to the container classes imported from Cocoa, this is manually I guess.
I wonder if adding a mutating keyword on the declaration would help
public mutable func addObject(anObject: AnyObject) mutable
That way that should throw a warning on a let usage.
But that keyword only exists on Swift.
They would have to go through all of them like they did with nullable keyword.
If you're wondering why I am using CFArray -> performance.
Structs are pretty slow since you'd have to copy it from the dictionary to mutate and then insert into the dictionary again.
Though, those numbers were with Swift 1. Will try with Swift 2 again, but given the nature of immutability, I suspect it will still be slower.
Now that I think about it. I might make my own generic structs that uses NSArray/NSDictionary internally. Though I wonder if you can pass structs by reference instead of copy, that would be more useful.
- solomone 11y agoI wouldn't call that a bug. That's like saying you can't do let a = Foo() a.addItem(i)
- seivan 11y agoIt's a bug in a sense that NSArray, NSSet, NSDictionary (The mutable ones) should have the keywords setup when they are ported with Swift headers. Naturally, that would be manual work though. Like the way they added nonnull, nilable or whatever its called to Obj-C
- mikeash 11y agoWhy would they have keywords added? Adding `mutating` to a func in a class is invalid, because the very concept makes no sense. The `mutating` keyword can only apply to value types, because it means "this func mutates the value in-place, so it needs mutable storage to invoke it." The "bug," if there can be said to be one at all (I don't see it), is that Swift collection types are value types, while Objective-C collection types are reference types. But given this difference, the lack of `mutating` on the mutating methods makes complete sense, and adding it would be bizarre, since it would be an error if you did it in your own code.
- mattdw 11y agoSwift seems to distinguish 'mutating' from 'changing'. The name 'array' in your example remains pointing to the same object, it's just that that object is being internally mutated. Not sure that there'd be a foolproof way to catch all possible mutations, so that may be the best they can do.
- supster 11y agoFor objects passed by reference, a Swift "let" signifies immutability of reference (not value); thus you can append to the NSMutableArray but not reassign to a different NSMutableArray. On the other hand a native Swift Array assigned via "let" would be immutable from both a value and assignment perspective.
- ecopoesis 11y agoThat's not a bug. Your array reference isn't changing, just the data in the object. Scala (which uses var and val for mutable and immutable) would do exactly the same thing. Heck, even Java (using final to mark immutable) would work like this. This is basically how every OO language works.
- myko 11y agoI think the poster understands that, it's just in Swift if you assign a Swift Array (not an NSArray) using let it is immutable both in reference and in whether or not items can be added or removed from it. That said, it's a quirk of the interop and I don't think Apple should spend time fixing it - rather developers should avoid NSArray within Swift.
- seivan 11y agoCan't avoid it for everything which is why I'm considering wrapping.
- xenadu02 11y agoRemember that Swift collection types have the semantics of copy-on-write. Under the hood they actually only copy if the collection is non-uniquely referenced. An Array<T> is a struct but uses a storage reference type under the covers. In theory the standard library is actually free to make common slices of arrays share storage so pure additions don't even require copying but I have no idea if it is actually implemented that way (neither String nor Array guarantee contiguous storage)
- hellofunk 11y agoIt definitely changes how a developer works in a language if they know they can depend on this kind of implementation. In Clojure, knowing up front that all data structures have shared persistence allows you to do things that you'd never consider in a language where this wasn't guaranteed. I think Swift could greatly enhance its power in the functional paradigm if indeed it did what you describe, but also making this clearly known to everyone who uses it.