Swift Dictionaries are Always Value Types
Tuesday, February 3rd, 2015More reading in The Swift Programming Language and I've come to the part about Arrays and Dictionaries. Specifically, a dictionary is treated as a Valu e, and that means that it's copied on every assignment and on all function or method calls. The significance of this, to me, is profound. One of the singularly most useful data structures for a coder is the dictionary (the other is the array), and to find out that passing around a dictionary makes a copy on each method call and on each assignment.
In the CryptoQuip codebase, we create a map of all the known words - where the key is the pattern of the word, and the value is an array of all known words with that pattern. As we run through the list of words (a file), we calculate it's pattern, and then add it to the array in the dictionary for that pattern. In clojure, we really compute all the patterns for the words, and then group them by their patterns.
We then pass this dictionary around to make it simple to find the possible words that a cypher text word could be. If the docs are as they have been written:
Whenever you assign a Dictionary instance to a constant or variable, or pass a Dictionary instance as an argument to a function or method call, the dictionary is copied at the point that the assignment or call takes place.
yet they also try to say this isn't an issue:
The descriptions below refer to the “copying” of arrays, dictionaries, strings, and other values. Where copying is mentioned, the behavior you see in your code will always be as if a copy took place. However, Swift only performs an actual copy behind the scenes when it is absolutely necessary to do so. Swift manages all value copying to ensure optimal performance, and you should not avoid assignment to try to preempt this optimization.
Sadly, StackOverflow isn't a lot of help, and this includes talking to someone in the Swift Language group in Apple. The advice appears to be: Wrap it in a class.
The reason being that all Classes are pass-by-reference as opposed to pass-by-value. While this certainly can solve the problem, it makes something that should be very simple a lot harder. I can see how to do this, and should we move ahead with the CryptoQuip solver in Swift, it can be done, but it seems like a hack.
Kinda seeing some of the cracks in the Swift language... not ideal, but it is what it is.