Addressing the ambiguity of attributes?

Does anyone else feel a bit frustrated that any and all new things now are preceded with an '@' - with no clear way to disambiguate attributes, macros, property wrappers, result builders etc? Some things are namespaced, others are hardcoded into the compiler. Case/naming seem to vary all over the place too. It's starting to feel like a mess.

I don't have a well-thought-out pitch to bring to the table - rather, I'd like to stimulate some discussion. However, something quick off the top of my head:

@Macros:
	#AutoCodable
	#AutoHashable
@Attributes:
	Sendable
	Available(iOS 14, *)
struct Thing {

}
3 Likes

My understanding is that we have two categories:

  1. Built-in attributes that are hardcoded into the compiler. These start with a lowercase letter: @available, @escaping, @propertyWrapper, @resultBuilder, @freestanding, @attached, etc.

    The only exception I can think of is @Sendable, which presumably starts with an uppercase letter because it's related to the Sendable protocol.

  2. "User-defined attributes", i.e. the actual property wrappers, result builders, macros, etc. defined in libraries. By convention, these should start with an uppercase letter.

3 Likes

The intent with @Sendable is that eventually we'd let you declare other protocols for the closure to conform to as well, in particular things like @Equatable and @Hashable that could be supported when the closure's captures are all equatable, and possibly other user-defined protocols with derivable default implementations.

7 Likes

There are also attributes in the Swift documentation with snake case: requires_stored_property_inits, and warn_unqualified_access.

But yeah my issue is you see something attached to a type, and it could be associated with any number of language/compiler features, and it isn't obvious which. I get that you can use your IDE to dig a bit deeper and inspect an attached attribute (sometimes), but it would be nice to understand in a glanceable way how a given attribute is augmenting my code.

For example, I imagine one day there could be a Hashable macro to move the synthesis from compiler to standard lib. If you then attach @Sendable and @Hashable to a type - to the layperson they look like they might invoke similar behaviours, but one is a macro that transforms your code, and the other is some other compiler thing.

1 Like