I don't use Swift on a daily basis, because it's effectively an Apple-only language.
So when I recently returned to it I found two new problems.
My code which ran just fine after being compiled with the Swift 5 compiler doesn't run correctly when I built with the 5.9-dev compiler. The latter produces runtime bugs that didn't exist before.
Looking at some sample code, I see more At expressions than before, for instance at-frozen, at-State, at-stateobject, and so on. Is there a complete list anywhere? What are each of these for? The documentation (to the extent that it exists) is vague. Don't these expressions make the code less readable?
Some "@ expressions" are built-into the compiler, like @available, @propertyWrapper, @dynamicMemberLookup. I don't know of any centralized lists of these, but it would be great if someone could share one.
Most others are provided by libraries like SwiftUI, in the form of Property Wrappers
Don't these expressions make the code less readable?
On the contrary, they vastly increase readability compared to the hand-rolled alternative.
Property wrappers let you extract reusable behaviour that's automatically applied to the getting or setting of values (like handler methods in JS or Descriptors in Python).
For example, everytime you write to a property marked @Published, your ObservedObject will automatically emit a objectWillChange event. If the @Published property wrapper didn't exist, you would have less @ signs in your code, but you would also need to do something like objectWillChangePublisher.send() on every property write. This is laborious, introduces crazy amounts of repetition and chances to forget to do it. Before you know it, you'll see questions on the forums looking like:
Asker: "Why did my view not update when I change this property?"
Answerer: "Because you forgot to objectWillChangePublisher.send()."
Asker: "Why can't the framework just automatically call that for me?"
And thus, property wrappers arise.
PS: but yeah, there’s a lot of @s now. I wish the built in ones used a different sigil
in my opinion, many things that currently use an @, like @usableFromInline should have been keywords or rolled into other attributes. and some things that do not use an @, like CodingKeys, should be using an @. everyone had a different opinion on those things, so we had to settle on something.
but the reason why we have so many attributes is because historically, it was politically easier to add a new attribute to the language, than it was to add a new keyword to the language. you will hear many rationalizations why ___ should be an attribute, but they all stem from the perception that keywords are more "heavyweight" than attributes.
What's left? @available, @convention(c), @objc – maybe they could use a different sigil indeed to leave @ solely for property wrappers (or vice versa).
Then there’ll be a forum post asking why there’s so many keywords.
I think the reality of the situation (and any in the industry) is harsh. If someone doesn’t keep up, they’ll get left behind. Someone wants to build an app, they need to take the time to understand the concepts they needed. But this doesn’t mean there couldn’t be less effort required to do so.
That can only be true if the reader immediately knows what they mean, but actually they are confusing. For instance:
at-state or at-stateobject seems redundant because every var property is state by definition.
at-frozen is confusing because there is already "let" (constants) and static, which have similar meanings. Maybe frozen refers to a princess or something?
at-published sounds like it is document related. Maybe "subscribable" would be more specific?
I totally agree hand rolled alternatives would be worse. When I was saying I'm getting @ fatigue I was more nodding at @MainActor, the custom property wrappers and result builders. So many libraries out there now have some attribute they introduce and end user code eventually gets littered with @something on top of the baked in ats. It's all a hodge podge of attributes now and more are coming. Not helping is the different colouring in Xcode. some are red some are purple, autocompletion many times breaks for attributes or doesn't exist
If you program for the Apple world you're bound to have some @objcs here and there too even if you hoped the old hag was dead and buried
While Swift always strived for readability I feel that in some parts it has become not unreadable but very noisy for lack of a better description and attributes are a major part of that
Plus if you have any dark thoughts of making your code performant you have to add even more obscure attributes. It baffles me actually, and it's probably worth its own thread, how (ultra) performance sensitive swift is not documented apart from the GitHub readmes that other people have already posted here. And those "docs" always come with almost a do-not-use-this, do-not-use-this-yet, are-you-sure warning.
I agree and agree that some are so key that they are essentially keywords, like @inlinable@escaping@discardableResult etc. My bad here too because even though I've been crawling these forums since their inception without participating or even having an account for quite a few years, I never voiced my opinion when I disagreed and maybe the balance would have leaned in favour of keywords. But I've seen all the discussions in all the pitches and reviews and indeed adding keywords was very heavily scrutinised, many times justifiably so considering the new-ness of the language.
True, but they (the property wrapper ones, at least) are option-clickable entities that you can lookup. It's no different from any other function or class.
Now consider the alternative:
An absolute cluster– of code like objectWillUpdate.send(), SwiftUI.allocateState(for: self), SwiftUI.state(for: self)[key] = value, etc. That would be less readable (lower signal-to-noise) ratio, and patterns would be implicit rather than explicit, extracted and named.
It's no different from any other kind of function, really. When you extract a function and give it a name, you do make code more opaque in one particular sense of the word. If callers don't know what the function does, it's less immediately clear than before. But of course, the hope is that the simplification you get from not having all your functions inlined, having them have names, and documentation, outweighs the indirection they add.
That's even more confusing. Are they talking about a US state like Kentucky? Or is State a verb, as in "I hereby state that..."?
In the past, Objective-C's designers and Apple pointed out the obvious that longer expressions are clearer and more specific. Calling a variable (which is already state) a State sounds redundant, and it doesn't tell the context.
As Uncle Bob once said, you can tell software quality by counting the number of WTF's that a newcomer emits per unit of time.
If a newcomer looks at something and says WTF too often, then it's crap.
Classic Programming Mistake #1: Using ambiguous, vague, nonspecific names for things that leave out context.