My reason for preferring var skipTable: [Character: Int] = [:] over the alternatives has to do with education and the order in which topics are introduced to programming students.
I am very strict about not using syntax or features a student hasn't learned yet, and not introducing things too early. As such, I teach data structures fairly early on, after control flow and functions, but before custom types. The syntax above lets me do that, as it uses a literal instead of an initializer for initialization (unlike var skipTable = [Character:Int]()) and does not require generics (unlike var skipTable = Dictionary<Character, Int>()).
There's no good reason for that, it's just one of those early days decisions that's hard to undo now. If to find some excuses: to distinguish which function to call:
func foo(_ x: [String : String]) {
print("dictionary version called")
}
func foo(_ x: [String]) {
print("array version called")
}
func foo(_ x: Set<String>) {
print("set version called")
}
foo([:])
without putting type explicitly at the call site:
foo([] as [String: String]) // not current Swift
Interestingly foo([]) call is unambiguous here (and it feels it should be ambiguous).
With [] for empty directories and along with making comma separators optional we could have supported conditional literals like so:
// not current Swift ahead
var foo: [String: String] = [
#if os(macOS)
"key" : "value" // comma is optional here
#endif
]
var bar: [String: String] = [
"hello" : "world" // comma is optional here
#if os(macOS)
"key" : "value" // comma is optional here
#endif
]
PS. it's better starting new threads instead of resurrecting old threads.