Understanding the Propertywrapper examples from the evolution document


I am trying to read and understand the property wrapper details from the evolution document and trying to run the examples provided in the document. I am having trouble in understanding some of the error messages, any input will be helpful.

Here is the example straight out of the evolution doc.

enum Lazy<Value> {
  case uninitialized(() -> Value)
  case initialized(Value)

  init(wrappedValue: @autoclosure @escaping () -> Value) {
    self = .uninitialized(wrappedValue)

  var wrappedValue: Value {
    mutating get {
      switch self {
      case .uninitialized(let initializer):
        let value = initializer()
        self = .initialized(value)
        return value
      case .initialized(let value):
        return value
    set {
      self = .initialized(newValue)

when i try to initialize the variable using the same as @Lazy var foo = 1234 I get the following error message.

error: property wrappers are not yet supported in top-level code
@Lazy var foo = 1234

I'm not sure what does this error really mean. Can someone please share some insight on the error and pre-requisit reading materials to understand the same?

Currently, they can only be a property, i.e., inside class/struct. So

struct Foo {
  @Lazy var foo = 123 // ok

@Lazy var bar = 123 // bad

Thanks @Lantua that makes sense now :). Then I think the document should be more explicit about it. It was not so obvious for me when I read it.

The document doesn't say anything about wrappers being unavailable for variables, because it describes what is the goal of the proposal, not the current state.

About pre-requisit reading materials to understand the error - I don't think there exists one. Do you think if someone wrote a glossary with a term "top-level code" in it would it help you understand this error?

@cukr Document starts by saying what problem it is trying to solve. And gives the above example. without wrapping the property inside a class or struct. That gives the perception that We should be able to write the property wrapper without the class/struct.

I'm not sure if you are trying to be sarcastic here.

That's because we should be able to write the property wrapper without the class/struct.

The unfortunate thing is that we cannot do that yet. In the future, when the whole proposal is implemented you would be able to do that.

I'm not sarcastic. I'm just trying to figure out what kind of resource would help other people understand similar errors. You were looking for some reading-materials, and I wanted to know what kind of reading materials would help.


But it is not mentioned in the restrictions/limitations on the usage either. May be one additional point in the current limitations will help.

I know it is hard to create a glossory of all the errors which can possibly occur. I found it really useful to understand the unsafe pointers presented in this article. May be something like this will be helpful (speicifically the table of syntax). If you have a glossary of errors you have encountered and fixed if you have documented it, I would be really happy to read through them.

but that would imply that the current behaviour is not a bug :(

If you tried to put current limitations into architectural plans, all the workers would go home the first day, because someone changed the plans for a building into plans for an empty field.

@cukr I was thinking more about how we could make or express the current limitations of any feature. How about throwing a meaningful errors to showcase the current limitation?

Instead of an error like this.

error: property wrappers are not yet supported in top-level code
@Lazy var foo = 1234

How about an error message like this?

error: property wrappers are not yet supported in top-level code. Property wrapper needs to be used inside a class/struct.

suggested useage:
    struct Foo {
      @Lazy var foo = 123 // supported

@Lazy var bar = 123 // Not supported yet!

This need not be an exact error message. But I hope you get the idea. This will be a better approach than trying to collate the list of possible error messages encountered.

Error messages are meant to be concise because they must be displayed in a variety of contexts where long messages don't work. Where a longer explanation is necessary, there are now educational notes for common trouble spots. You're definitely right that we would do well to expand the number of available educational notes to help users.

However, like @cukr, I'm having trouble understanding what about this particular error message is currently unclear. Your example seems to be restating "not yet supported" as "not supported yet" (these mean the same thing in English) and illustrating what "top-level code" means. Is that the term that you're having trouble understanding?

If so, we should make sure that there's a glossary of some sort in The Swift Programming Language; it's a pretty commonly used term (like "free functions") that I think we have to be able to assume users either know or are able to look up for the purposes of error messages.

1 Like

Yep, "top-level code" is not so clear and concise.

If it so common then, it sounds like a good idea to have the current jargons used when displaying the errors.

@xwu Adding to my previous point, If you missed to scroll the message. I was pointing at the context which it needs to be used aswel.

That's just a rewording of "not top-level code." It's fine to point out that that terminology is unclear; however, "top-level" is pretty commonly used, and in more than just Swift. I think it's as reasonable for an error message to expect users to know that term as it is to expect users to know what a variable or a class is. It would certainly be reasonable to add a request for a glossary in TSPL which explains it to users, though, if it's not already covered in that text.

Terms of Service

Privacy Policy

Cookie Policy