Swift.Array "let" behavior is misguided
Originator: | brent | ||
Number: | rdar://17136760 | Date Originated: | 2014-06-03 |
Status: | Duplicate/17192555 | Resolved: | |
Product: | Developer Tools | Product Version: | Xcode 6A215l, swift-600.0.34.4.5 |
Classification: | Other Bug | Reproducible: | Always |
Summary: Arrays created with "let" should not allow their elements to change. Doing so breaks the principle of least surprise and is likely to cause bugs in concurrent code. Steps to Reproduce: 1. Open an Xcode playground. 2. Type the following: let array = ["a"] array[0] = "b" Expected Results: A "Cannot assign to the result of this expression" error. Actual Results: The array is mutated. Comments: I understand that Swift can perform optimizations on semi-mutable arrays that it can't perform on fully mutable ones. That's great! I want you to perform those optimizations where you can! But that doesn't mean you should overload "let"—which for all other struct types means "this is immutable"—to indicate an array is semi-mutable. When I pass an immutable array to another function—or, God forbid, to a block on another queue—I need to be able to trust that the array won't change behind my back. Sure, I can call unshare() defensively, but then what's the point of having the optimization at all? It'd be much better to create a FixedArray type or use a different keyword to indicate when you actually want this optimization. As it is, I'm likely to stick with NSArray—and that's a damn shame. I want Swift.Array's type safety, but not at the cost of creating async bugs.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!
Duped as rdar://17169043. Thanks.
The Swift book actually specifically says "The unshare method cannot be called on a constant array."
So it seems like the only way to safely use constant arrays would be to copy them explicitly.