Confusing computed property with closure initializer, is there a better way?

I just spent a good hour being confused was to why a function seemed to do its job, and then the results would disappear. Turns out I had used

var foo: [Int] { ... } 

instead of

var foo: [Int] = { ... }()

... so I was zapping the entire array every time I looked at it.

Is there a better way to keep those clear in my head?

I honestly wish we had a better syntax for the latter, so that we wouldn't try to write the two very similar things. You can fake it with a helper function…

func run<Result>(_ action: () throws -> Result) rethrows -> Result {
  return try action()
}

var foo: [Int] = run { ... }

…but is everyone going to use that?

2 Likes

Kotlin has the very useful with method for this purpose.

1 Like

Yeah, that's a good point, most of the time you're initializing something specific, and people have been trying to workshop with for Swift for a while now.

As I think about it more, I'd kind of like there to be a computed attribute, in parallel with var and let.

let: not assignable, not changing
var: assignable, changing
computed: not assignable, changing

And of course in the grand tradition of computer science, I will add, but not actually propose,

inscrutable: assignable, not changing

This last would take and do something with assignments, but when read will return some immutable value picked by the developer. I don't know that this would be useful to anyone, but huzzah, we are complete!