What does "property" mean now?

Before Swift 5.4, my mental model for what "property wrapping" was, was the same as officially documented:

When you use a property wrapper, you write the management code once when you define the wrapper, and then reuse that management code by applying it to multiple properties.

You apply a wrapper to a property by writing the wrapper’s name before the property as an attribute.

When you apply a wrapper to a property, the compiler synthesizes code that provides storage for the wrapper and code that provides access to the property through the wrapper.

That is to say, the "property" being "wrapped" was the name that came after @Wrapper var—which had to be what was previously known as a property. But now, property wrappers can be applied to local variables. So, has Swift 5.4 redefined what "property" itself means?

  1. Is a "local variable" actually a "function property" or "closure property" now?
  2. Has Swift 5.4 accidentally solved the problem of not having a term for both let- and var-things? Are they all properties?
  3. And if the term "property" has just been extended from applying only to type-scope, is a function-scoped function now a "function method"? Or should the term "method" be avoided when talking about Swift, as "function" and "property" are all that's needed, aside from scope?

Alternatively, it's possible that nothing needs to change other than the documentation, and our mental models: if the properties being "wrapped" are wrappedValue and projectedValue, that could work too. But that's not how the feature is advertised.

The definitions for "property" and "method" never felt at home to me in Swift, which has a lot of nesting power outside of just the one right inside a type. We can of course be hand-wavy when talking about this stuff, but I think 5.4 just added the first new level of confusion about the concept since Swift's initial release. It would be nice to have precise, unconfusing language.


The feature is named after its most important use-case, but is generalized so that it can apply in similar situations. It isn't meant to suggest that local variables are properties.


This is the waving of the hand I mentioned. :slightly_frowning_face:

So we do need a term that covers both properties (type- or instance-level) and block variables (local or global), and then replace "property wrappers" with "X wrappers," where X is the new general term?


The official documentation does refer to the general case of another feature as "computed variables", which are then known as "computed properties" when they are nested exactly at the level of type scope.

So what we're probably dealing with now are variable wrappers, with property wrappers being the special, but most-used, case.

That solves my issue #1. I'd be happy enough with that, because #1 is brand new, and #s 2 and 3 haven't been addressed for 6.5 years, and I don't expect that they will be. They also don't require lying.

It may not seem a big deal to some, but I try to adopt a policy of never lying unless it's required to avoid catastrophe. Using the term "property wrapper" on something that is not a property is a lie that I would have to use every day, and I don't want that in my life.

We might soon have parameter wrappers too, again reusing the property wrapper name and mechanics.

It's already brought up back in the review period. And a change of this magnitude would need to be on the level of active harm (which I personally won't dive into).


Attaching a property wrapper to a parameter makes that parameter a computed variable local to the function body

Still sounds like a variable wrapper to me.

For what it’s worth, this terminology isn’t new with property wrappers on local variables in Swift 5.4. For example, Swift has property observers and computed properties. Both of these features also apply to local variables.


The official documentation does not refer to "variable observers", but people who use them do.



I wonder what is the point being made. What was a property still stays a property; what was a local variable still stays a local variable.

The existence of a supporting feature that simply could be extrapolated onto another case does not magically turn a local variable into a property (of what?) just because it was initially named a certain way — being a local variable (unsurprizingly) means being a variable declared locally and not being something that has no @'s in front of it or observers attached to it.

I have a hard time imagining that somebody who is already familiar with the concept of variables vs. properties will become anywhere close to confused when encountering these supporting features in the code, even if in an ideal world these features could've been named more generically.


Most developers interact with code in a solitary, non-auditory way. They often don't even know how to pronounce what they're seeing out loud, or have to talk about what the code looks like with other human beings. This is fine! It can get the job done, and an understanding of syntax is completely possible without knowing related terminology.

I make educational Swift-based videos for a living, where I constantly refer to what we're observing, aloud. The non-verbal processing doesn't work for the medium. And anything that we can speak or write about with clear, truthful terms, won't harm the internal wordless understanding you're talking about.


Somewhat related: is there a better word for “local variables” — where “variable” seems to include constants as well as variables (let as well as var)?


I’m not sure what the harm or untruth is here. Things are often described by their most common uses. If you put your afternoon trail mix snack in a sandwich bag, it’s still a sandwich bag, not a “food item bag.” If you bring those snacks to a party in a book bag, no one would wonder why you brought books to a party.

The whole reason there’s a specific adjective attached to “wrapper” is to help clarify a very generic term by describing how it’s most often used. It would be strictly worse to water it down.


I don't necessarily think "variable" is a misnomer. The value of a let-constant can change, for example, across runs of a program or invocations of a function if it's a local variable (e.g., based on input). let also means something different depending on whether the object has value semantics or reference semantics. Even the term "type" can mean different things depending on whether you're talking about a static type or a dynamic type. There are so many different dimensions to a program that it's often not helpful to talk about things using general terms. Pedantry is important :slightly_smiling_face:


This seems like a great point at first, but I don't think it holds up to scrutiny.

"Sandwich" is the size of the bag, not a description of its contents. It becomes a trail mix bag when you put trail mix in it: specifically, a bag for an amount of trail mix equal to or less than the volume of a sandwich.

sandwich = variable
trail mix = property

Bookbag is a regional term. Where I come from, a backpack is only a bookbag when used by a student.

backpack = variable
bookbag = property

This seems to have devolved into a general philological discussion which, while fun, is the kind of fun best had on twitter, not here where it's off topic.

As John said in the first reply,

The feature is named after its most important use-case, but is generalized so that it can apply in similar situations.

There is not much to be gained from debating this, as the name isn't changing and shouldn't be taken as having some deeper meaning that can be further applied.


What about Augmented Variables?

Terms of Service

Privacy Policy

Cookie Policy