Remix.run Logo
willtemperley 2 days ago

Which keywords would you get rid of and why? You don't have to use all of them!

fauigerzigerk 2 days ago | parent | next [-]

I would remove result builders and all other uses of @attributes that change the semantics of the code (e.g property wrappers).

I would remove the distinction between value types and reference types at the type level. This has caused so many bugs in my code. This distinction should be made where the types are used not where they are defined.

I would remove everything related to concurrency from the language itself. The idea to let code execute on random threads without any explicit hint at the call site is ridiculous. It's far too complicated and error prone, which is why Swift designers had to radically change the defaults between Swift 6.0 and 6.2 and it's still a mess.

I would remove properties that are really functions (and of course property wrappers). I want to see at the call site whether I'm calling a function or accessing a variable.

I would probably remove async/await as well, but this is a broader debate beyond Swift.

And yes you absolutely do have to know and use all features that a language has, especially if it's a corporate language where features are introduced in order to support platform APIs.

fingerlocks 2 days ago | parent [-]

I agree with you about result builders, silly feature that only exists for SwiftUI.

But a lot of what you said, except for the concurrency and property wrapper stuff, largely exists for Obj-C interop. The generated interface is more readable, and swift structs act like const C structs. It’s nice.

quietbritishjim 2 days ago | parent | prev | next [-]

I'm not a Swift user, but I can tell you from C++ experience that this logic doesn't mitigate a complex programming language.

* If you're in a team (or reading code in a third-party repo) then you need to know whatever features are used in that code, even if they're not in "your" subset of the language.

* Different codebases using different subsets of the language can feel quite different, which is annoying even if you know all the features used in them.

* Even if you're writing code entirely on your own, you still end up needing to learn about more language features than you need to for your code in order that you can make an informed decision about what goes in "your" subset.

cloogshicer 2 days ago | parent | prev | next [-]

But you have to know all of them to read other people's code.

To answer your question: I would immediately get rid of guard.

Also, I think the complexity and interplay of structs, classes, enums, protocols and now actors is staggering.

willtemperley 2 days ago | parent [-]

I'm surprised, guard is really useful, especially when unwrapping optionals. It's terse, explicit and encourages defensive programming.

internal should definitely go though.

cosmic_cheese 2 days ago | parent [-]

The absence of guard in Kotlin is one of those things that regularly trips me up when bouncing between it and Swift. Rather than Swift losing guard I’d prefer if Kotlin gained it.

iamcalledrob 2 days ago | parent [-]

I think the ?: operator ends up being a decent alternative, e.g.

  // Swift
  guard let foo = maybeFoo else {
    print("missing foo")
    return false
  }

  // Kotlin
  val foo = maybeFoo ?: run {
    print("missing foo")
    return false
  }
Unless there's a use case for guard I'm not thinking of
cosmic_cheese a day ago | parent [-]

It’s a decent alternative, but to someone not familiar with the language what’s going on isn’t as clear.

rudedogg a day ago | parent | prev | next [-]

> You don't have to use all of them!

You sure pay for the language complexity in high compile times though. Swift is slow, like really slow. I’ve been with it since like v1.2, and its been getting progressively worse for a while IMO. Complex language features (Lets do a borrow checker! Lets do embedded!) and half of the shit isn’t being used internally as far as I can tell

merlindru 2 days ago | parent | prev | next [-]

i would get rid of associatedtype, borrowing, consuming, deinit, extension, fileprivate, init, inout, internal, nonisolated, open, operator, precedencegroup, protocol, rethrows, subscript, typealias, #available, #colorLiteral, #else, #elseif, #endif, #fileLiteral, #if, #imageLiteral, #keyPath, #selector, #sourceLocation, #unavailable, associativity, convenience, didSet, dynamic, indirect, infix, lazy, left, mutating, nonmutating, postfix, precedence, prefix, right, unowned, weak, and willSet

willtemperley 2 days ago | parent [-]

It's true that internal is pointless.

Focusing on the keywords rather than the macros, I think the rest of them have legitimate use cases, though they're often misused, especially fileprivate.

merlindru a day ago | parent [-]

this is gonna sound ranty, but it's straight from the heart:

i think most of them are pointless. not every feature needs to be a new keyword. stuff could be expressed within the language. if the language is so inflexible in that regard that it's impossible to express stuff without a keyword, use macros for gods sake.

why is there a need to have a "convenience func" declaration?

why is "didSet" a keyword?

what about "actor"? most other languages don't have nearly as many keywords and manage to express the idea of actors just fine!

eptcyka 2 days ago | parent | prev | next [-]

You can take this approach in personal projects - with teams you need to decide on this and then on-board people into your use of the language. This does not work.

willtemperley 2 days ago | parent [-]

Yes exactly, it’s easy to blame a language when really it’s a team problem.

troupo 2 days ago | parent | prev [-]

1. You don't have to use it all, but someone will. And there are over 200 keywords in the language: https://x.com/jacobtechtavern/status/1841251621004538183

2. On top of that many of the features in the language exist not because they were carefully designed, but because they were rushed: https://news.ycombinator.com/item?id=47529006

uasi 2 days ago | parent | next [-]

That number is unfairly exaggerated. The list includes ~40 internal keywords used only by language developers, plus dozens of tokens that would be called preprocessor directives, attributes, or annotations in other languages (e.g. `canImport` as in `#if canImport(...) #endif`; `available` and `deprecated` as in `@available(*, deprecated) func`).

dematz 2 days ago | parent | prev [-]

are there actually 217 keywords? Just wondering what the difference between that file and https://docs.swift.org/swift-book/documentation/the-swift-pr... (a mere 102 keywords)

merlindru 2 days ago | parent [-]

That file is the compiler's list of reserved keywords, so some of them may not have been added to docs, or they're experimental/internal/...

I'm not 100% sure but I think the swift doc you linked is missing at least a dozen keywords so the truth probably lies in the middle

dematz 2 days ago | parent [-]

Ah makes sense, personally I wouldn't consider reserved but unused words as keywords in the sense that you don't need to know them to read the language (even though they're keywords in some other technical sense). I was curious because I just tried counting number of keywords by language and it seemed surprisingly ambiguous/subjective/up to the language to say what's a "keyword" vs some type of core module. So my attempt (https://correctarity.com/keywords) probably has mistakes...