News for hackers. Stuff that matters.
Re:Swift System Is Now Open Source by dmitriid on Friday September 25, 2020 @04:07PM (#24593628)
I will gather a lot of downvotes, but still: I find Swift a very haphazardly designed language with very little foresight and forethought. This is further compounded by its standard libraries which are directly lifted from MacOS with all of their idiosyncrasies and huge incompatible changes from version to version.

For what it's worth, [1] [2] [3] [4]

[1] A type system that can't cope with SwiftUI: https://tonsky.me/blog/swiftui/

[2] More syntax to shake a stick at https://twitter.com/dmitriid/status/1276482336486576133

[3] Even more syntax weirdness https://twitter.com/bradfitz/status/1285302091544576000

[4] Standard library between versions: https://twitter.com/dmitriid/status/1201441652507844608 File manipulation functions on String, great design.

Re:Swift System Is Now Open Source by valuearb on Friday September 25, 2020 @04:50PM (#24593955)
So you ding the language because of a suboptimal choice made by one tool for it?

The good and bad of Swift is the regular breaking updates. Sure it’s a pain when things change, but it’s also healthy when they improve, and almost every change has been an improvement.

A language as simple as C can slowly grow without breaking existing source code. But it’s also never been able to address its most significant flaws.

Re:Swift System Is Now Open Source by dmitriid on Friday September 25, 2020 @04:55PM (#24594000)
> So you ding the language because of a suboptimal choice made by one tool for it?

I provided 4 different links showing multiple different features in the language I find suboptimal.

> Sure it’s a pain when things change, but it’s also healthy when they improve, and almost every change has been an improvement.

It's a very dubious statement at the very least.

> But it’s also never been able to address its most significant flaws.

Can Swift address its flaws even with its breaking changes? So far its been piling on more and more syntax, and continuously breaking its standard library (whose design choices like writing to files from Strings are very dubious)?

Re:Swift System Is Now Open Source by saagarjha on Friday September 25, 2020 @07:06PM (#24594976)
Swift is an extremely well designed language, probably one of the best I have encountered. Dinging it for its syntax is something that I didn't think I would ever hear. To respond your links–SwiftUI is not part of Swift, so 1 and 2 are not relevant; 3 is clearly explained and is never an issue in practice, and 4 is you faulting the language for being able to interface with APIs designed in the last century–you might as well laugh at it open(2) taking a bitmask.
Re:Swift System Is Now Open Source by dmitriid on Friday September 25, 2020 @07:30PM (#24595097)
> Dinging it for its syntax is something that I didn't think I would ever hear.

Not just syntax, but the amount of it, and the amount of special cases in it.

> SwiftUI is not part of Swift, so 1 and 2 are not relevant

SwiftUI exposes deficiencies in the "one of the best designed languages" and shows how Swift fails to scale in complex scenarios.

(1) Shows that its design cannot cope with anything complex. You have to write clunky wrappers for `if` and `foreach` (but not for while and for, apparently), because the design of the language didn't have place for expressions. The type system cannot handle complex requirements of the library and can't provide better facilities than Java.

(2) Shows just how bad the design decisions are in the language that they all but force you to write code this way. There's syntax upon syntax with no internal consistency or actual design to figure out how they all operate with each other.

And Swift UI forces more half-baked escape hatches (like the `some` "type", like the lambda changes described in (1)) etc.

I'll just once again expose my favorite piece of code ever:

  guard let self = self { return }
instead of

  if self == nil { return }
This is not an "extremely well designed language". These are badly thrown together pieces of half-baked ideas.

(3) Once again shows just how badly it's designed. Or, rather, how badly the parser is designed that it can't reliably figure out what is going on. In a language that has no significant whitespace you have to care about significant whitespace. Great design.

(4) I'm faulting the design of the standard library that is only compounding the problems already present. Many languages managed to figure out standard libraries that don't make you read and write files from a string object, or need 15 lines (different every year) of code to figure out how to write/read a file. This only continues to show that very little thought is going into this project, as they are being pressured for time to deliver "something".

Re:Swift System Is Now Open Source by skohan on Saturday September 26, 2020 @02:31AM (#24596850)
Guard statements are great.

First of all, this is still perfectly valid swift:

    if self == nil { return }
But guard is really nice, because it signals to the reader of a code block that if the guard condition can't be met, execution cannot continue past the guard. It does a lot to signal intent which using an if statement for early return does not.

It's something I sorely miss in Rust for example.

Re:Swift System Is Now Open Source by dmitriid on Saturday September 26, 2020 @02:43AM (#24596895)
> It does a lot to signal intent which using an if statement for early return does not.

Since every single language has an if statement, we clearly know what intent an if block signals.

If the if condition is not meant, execution cannot continue. See? Easy.

The only reason guard exists is not to aid the reader, but to aid the compiler to recognise nullability checks. That's about it. It really is a very specific if statement that is given a special treatment. And all comparisons of how great it is compared to an if statement I've seen are hillariously funny in how they willingly lie about ifs. Starting with the actual Swift docs [1]:

> Using a guard statement for requirements improves the readability of your code, compared to doing the same check with an if statement. It lets you write the code that’s typically executed without wrapping it in an else block

Here's how people take it to heart [2]:

> Without using guard, we’d end up with a big pile of code that resembles a pyramid of doom. This doesn’t scale well

Nope, you don't end up with a pyramid of doom, and yes it does scale well, provided you language designers actually design the language.

[1] https://docs.swift.org/swift-book/LanguageGuide/ControlFlow....

[2] https://thatthinginswift.com/guard-statement-swift/

Re:Swift System Is Now Open Source by skohan on Saturday September 26, 2020 @03:19AM (#24597020)
> Since every single language has an if statement, we clearly know what intent an if block signals.

Guard has different semantics than if. For instance, I can write:

    if self == nil { 
        ... do some cleanup
        return 
    }
Or:

    if self nil { 
        ... do something else without returning 
    }
If it's a simple early return, then yes it's pretty easy to tell the intent. But imagine that I have to do some complex cleanup work over many lines before the return. In the case of a guard, I can look at the guard statement and immediately know that this block of code must end the control flow within this function. With an if statement, I have to read and parse the content of the block before I can understand that execution should not progress past this block.

This is especially relevant when you're maintaining code which was written by someone else. With an if statement, you might accidentally remove a return statement from an if block which is required for correctness, and you may not find out about it until you run your program (or in the worst case after you release your code, and it causes unexpected bugs in production). With the guard statement, the compiler will enforce this constraint. It's one of many tools which Swift gives you to help you write correct code.

Also, with your example:

    if self == nil { return }
I assume you are alluding to languages where self would be implicitly unwrapped in this case, so it can be treated as a concrete instance rather than an optional after this statement. IMO it is a strength of swift that you don't have this magical conversion of an optional to a concrete value which never explicitly written, but is inferred by the compiler. Guard offers clarity and consistency about exactly where the unwrap happens, and it's barely more verbose than a bare if statement. IMO this is a very elegant solution, and in practice it's something I miss in languages which don't have it.
Re:Swift System Is Now Open Source by dmitriid on Saturday September 26, 2020 @07:45AM (#24598039)
> Guard has different semantics than if.

Yes, it has. But why? Everyone parrots the same "different semantics" excuse never bothering to ask why.

The only reason `guard` exists is to manually tell the compiler to do a nullability check. And that is it. It's a very small, very specific case wrapped into a separate syntax of its own because the compiler and the type checker are just not good enough.

  guard X else {}
is exactly the same as

  if X is not null {} // pseudo code
but the compiler/type checker are not good enough to know that once null checks are passed in a statement, it's safe to use that value in the code that follows.

This leads to horrendous piles of useless code like the one I showed:

  guard let self = self else { return }
How can one look at that and say, "yup, that's good design"?

> But imagine that I have to do some complex cleanup work over many lines before the return. In the case of a guard, I can look at the guard statement and immediately know

And immediately know almost nothing. Except that it's a very specific `if` case that returns. Which brings us to:

> you might accidentally remove a return statement from an if block which is required for correctness, and you may not find out about it until you run your program (or in the worst case after you release your code, and it causes unexpected bugs in production).

It won't cause issues if the language is actually properly designed. Because the variables you'll use will not checked for nullability in this case. And even Java will warn you with "potentially null value". But Swift can't do that without a `guard` statement. Go figure.

> IMO it is a strength of swift that you don't have this magical conversion of an optional to a concrete value

Yes, you do. You wrap it in a guard statement, assign a variable to itself, and poof, magic, it's suddenly unwrapped.

Re:Swift System Is Now Open Source by jasamer on Saturday September 26, 2020 @10:00AM (#24598910)
The difference between guard and if isn’t really about optionals. ‘guard x ...’ tells you that after the guard block, ‘x’ is the case. If x is a Boolean, it’s true; if it’s a matched pattern, it has matched, if it’s a ‘if let’, the value is non-nil.

A guard must return if the condition doesn’t match. There’s no such requirement for if.

I also like that unwrapping is explicit in Swift. ‘if/guard let x = optional’ is the syntax for unwrapping. ‘optional == nil’ is the syntax for checking whether an optional is nil. Why would the latter do any unwrapping? The first time I saw that syntax in Kotlin, I thought that it’s weird to add functionality like this to a normal looking if.

Re:Swift System Is Now Open Source by skohan on Saturday September 26, 2020 @08:47AM (#24598407)
> Everyone parrots the same "different semantics" excuse never bothering to ask why.

It's like you didn't even read my comment, I gave a reasoned answer why it's different. It gives a queue to the user that the condition must be met, or else there will be an early return.

The example you gave is also not equivalent - here you have:

    guard X else { /* branch A */ }
    // Branch B
And here you have:

    if X is not null {
        // Branch B
    }
    // Branch A
The problem with your argument is that you are taking a subjective preference - that magical unwrapping via if-statements is the best form of unwrapping - and stating it as if it is an objective fact. You haven't actually given any arguments for why guard is an inferior approach beyond basically saying: just look at it, it's bad language design. Why is it bad?

> It won't cause issues if the language is actually properly designed. Because the variables you'll use will not checked for nullability in this case. And even Java will warn you with "potentially null value". But Swift can't do that without a `guard` statement.

Again, it's not a question of proper/improper design or a failure of the compiler. The designers of swift made a conscious decision to provide exactly 3 ways to unwrap an optional:

1) the force unwrap `!` operator,

2) the `if let` statement,

3) the `guard let` statement

Just because that is not the exact design you would prefer does not make it a bad design.

You're also ignoring the uses for `guard` beyond null checking. For instance, if I wanted to check that my arguments are within a certain bounds, I could do something like this:

    func foo(x: Int) -> Int {
        guard x >= 0, x <= 42 else { return 0 }
        return 2*x
    }
This has nothing to do with "manually tell[ing] the compiler to do a nullability check ... because the compiler and the type checker are just not good enough" - it's about having an explicit language construct to signal that you do not want to continue with the logic of this function if the condition is not met.

> Yes, you do. You wrap it in a guard statement, assign a variable to itself, and poof, magic, it's suddenly unwrapped.

These are actually very different things.

In this statement:

    if x == nil { ... }
you are taking the conditional (`x == nil`) and giving it this magic side-effect that once it's executed, a new variable of a separate type is created and will replace `x` until the end of execution. Every other conditional simply evaluates to a boolean, so why should this one special case have this side effect where it's also declaring and assigning a new variable?

To contrast that with the statement which bothers you so much aesthetically:

    guard let self = self else { return }
Here the `let <identifier> = <value>` denotes the fact that you are declaring and assigning a new variable here, which is why the type change can take place. It happens to have the same name as the previous `self`, but every aspect of this is consistent with the rules of the language, and there is no special case being created here.

You may not like it, and that's fine, but your personal taste does not reflect an objective truth about language design. Tens of thousands of swift developers around the world are able to understand the motivation for, and benefits of `guard` statements just fine. If you are bizarrely confused or angered by them, it does not mean they are categorically bad.

Re:Swift System Is Now Open Source by saagarjha on Friday September 25, 2020 @07:53PM (#24595231)
I'm not interested in talking about SwiftUI, but you claiming that its type system is on the same level as Java's is just hilariously off-base. The "some Type" thing is fairly standard type erasure. Your "favorite piece of code" (which, FWIW, is missing an else on the guard) has different semantics than the other snipped you present because it rebinds self to a non-optional type, whereas the second one doesn't. The parser is largely whitespace agnostic, just like pretty much every other language. Oh, maybe you were going to bring up C++, the one where you have vexing parses and "most" vexing parses and until recently couldn't put >> down without it looking like an operator? Or maybe Rust, where you need turbofish or :: to help the parser out? In Swift at least the issue you mentioned doesn't actually show up if you care about your code style…

Oh, and for the last point, I suggest you read the article :P

Re:Swift System Is Now Open Source by dmitriid on Saturday September 26, 2020 @02:33AM (#24596857)
> I'm not interested in talking about SwiftUI, but you claiming that its type system is on the same level as Java's is just hilariously off-base. The "some Type" thing is fairly standard type erasure.

It amazes how people completely ignore everything against some one thing they can potentially defend.

Once again, SwiftUI exposes deficiencies in the language, no matter if you care about it or not. Let's take it from the top, shall we?

- Swift UI says: hey, I need to have a list of values inside my nice little functions, what can yo give me? Swift: I can give you Java:

  static func buildBlock<C0, C1>(C0, C1) -> TupleView<(C0, C1)>

  static func buildBlock<C0, C1, C2>(C0, C1, C2) -> TupleView<(C0, C1, C2)>

  static func buildBlock<C0, C1, C2, C3>(C0, C1, C2, C3) -> TupleView<(C0, C1, C2, C3)>

  static func buildBlock<C0, C1, C2, C3, C4>(C0, C1, C2, C3, C4) -> TupleView<(C0, C1, C2, C3, C4)>

  static func buildBlock<C0, C1, C2, C3, C4, C5>(C0, C1, C2, C3, C4, C5) -> TupleView<(C0, C1, C2, C3, C4, C5)>
- SwiftUI: I obviously need need some conditional and list management logic in my nice little lambdas. Swift: well, our "best designed language" can only give you Java. Because our "best designed language" has skipped class on language development of the past 40 years and can't even imagine that conditional statements can be expressions, for example

  static func buildEither<TrueContent, FalseContent>(first: TrueContent) -> _ConditionalContent<TrueContent, FalseContent>

  static func buildEither<TrueContent, FalseContent>(second: FalseContent) -> _ConditionalContent<TrueContent, FalseContent>

  static func buildIf<Content>(Content?) -> Content?
> The "some Type" thing is fairly standard type erasure.

Once again, the only reason `some` exists is to aid the compiler. Because the compiler in "the best designed language" cannot figure out the difference between protocols and types on its own.

In general, in Swift and you have to constantly manually aid the compiler in everything. Also see `guard` below.

> Your "favorite piece of code" (which, FWIW, is missing an else on the guard) has different semantics than the other snipped you present because it rebinds self to a non-optional type, whereas the second one doesn't.

Yeah, yeah. I've seen the "it's different semantics" argument everywhere. It's not "different semantics". The only reason this exists is because they rushed the language out, and the compiler and the type checker was very limited. The only reason guard exists is to force nullability checks by the compiler. It's an inelegant and clunky clutch to aid the compiler. That is it. "The best designed language" could instead have this:

   if x == nil { return }

   // the compiler knows that x is now not nil, 
   // it's no longer an optional type beyond this point

> The parser is largely whitespace agnostic, just like pretty much every other language. Oh, maybe you were going to bring up C++

No I'm not going to bring it up, but it's funny how you brought it up.

Re:Swift System Is Now Open Source by saagarjha on Saturday September 26, 2020 @05:06AM (#24597419)
I haven’t said the language is perfect; I think I probably know more about where the language has issues than most people would. The lack of variadic generics is an annoying limitation they’re working on bringing to the language, as they are with improving the situation around building conditionals.

Actually, the reason I chose to refuse to engage with you about SwiftUI is that Swift doesn’t support ever programming paradigm in existence, nor should it. The fact that SwiftUI is running into issues where it is trying to use language features that don’t exist and then shoehorn them into the language retroactively is not really a great situation. That said, you claiming (multiple times!) that the language had no thought put into it and that it’s the same as Java is just outright trolling/bait at this point. The language has had a huge amount of effort put into it, many of the questionable decisions made earlier have been rolled out; at this point its type system is really at a similar place Rust or Scala’s is.

The lack of conditional statements being expressions (note: the ternary operator does exist) and type narrowing is a conscious choice, not something that the language has to have in order to “be modern” or some sort of evidence that this wasn’t considered. Type narrowing in particular is very common in languages that interface with code that is not well typed (TypeScript with untyped JavaScript, Kotlin with unannotated Optionals and inheritance hierarchies from Java) and Swift has generally had a much better interface with system libraries than that (this being largely controlled by Apple, they can roll out annotations fairly widely). Statement expressions are just a choice that Swift does not choose to have, although as see with function builders perhaps Apple will force it into the language anyways. And type erasure is good not only for the compiler but it’s also a huge benefit for users and API designers: it allows for “class cluster” designs, it keeps users from having to see SomeMonsterGeneric<Wrapper<Type1, Type2, Type3>, OtherGarbage> for no reason.

Re:Swift System Is Now Open Source by dmitriid on Saturday September 26, 2020 @07:54AM (#24598093)
> Swift doesn’t support ever programming paradigm in existence, nor should it.

Of course it shouldn't. But going ahead and saying that "we shouldn't look at SwiftUI" for whatever reason stops most of the discussion about the deficiencies in the language.

Look, even you are saying things like this:

-- start quote --

The lack of variadic generics is an annoying limitation...

The fact that SwiftUI is running into issues... and then shoehorn them into the language retroactively is not really a great situation.

-- end quote --

You are basically repeating my words, but somehow I'm wrong in my assessment.

> that the language had no thought put into it and that it’s the same as Java is just outright trolling/bait at this point.

When you say that "lack of variadic generics is an annoying limitation" and "language features that don’t exist and then shoehorn them into the language retroactively" it's all right. When I say the same things, it's trolling. Got ya.

> The lack of conditional statements being expressions (note: the ternary operator does exist) and type narrowing is a conscious choice, not something that the language has to have in order to “be modern”

That's why SwiftUI has to "retroactively shoehorn" things like `buildEither<TrueContent, FalseContent>` because a "best designed language" doesn't have any facilities to, well, facilitate this.

> although as see with function builders perhaps Apple will force it into the language anyways.

Me: Swift lacks this and that.

You: You are a troll, and you are wrong, and this is a good design decision <literally half a sentence later> it will likely become a part of the language because <a few paragraphs before> there are features that don't exist in the language

> And type erasure is good not only for the compiler but it’s also a huge benefit for users and API designers: it allows for “class cluster” designs, it keeps users from having to see SomeMonsterGeneric<Wrapper<Type1, Type2, Type3>, OtherGarbage> for no reason.

There's literally no reason to have SomeMonsterGeneric<Wrapper<Type1, Type2, Type3>, OtherGarbage>. The only reason `some` exists is, and I repeat myself, because the compiler and the type checker literally can't distinguish between a type and a protocol without the developer babysitting them.

Re:Swift System Is Now Open Source by saagarjha on Saturday September 26, 2020 @10:24PM (#24603712)
Ok, I'll summarize myself once more and then stop trying: Swift is not perfect, but it's way better than Java. Some generally useful features are missing that were identified early but were put on the backseat for now because other things took priority, but they might be finally be coming now. SwiftUI is wrong because it is trying to use language features that don't exist, ones you think are "obvious" to include but I say are not necessarily "better".

The reason I suspect trolling is that you have repeatedly taken my comments out of context, glommed them with other things that are not related, and then responded to that strawman, plus created what I can only refer to as "bait" because I have to waste my time responding to them when I could be having a much more productive conversation. So tell me, would you rather talk about how Swift's type system is the same as Java, how the compiler is designed by incompetent fools who rush out releases, and how any language that doesn't include the three features you brought up is automatically stupid, or maybe we can discuss this more productively from the viewpoint of "why didn't Swift include these things I like?" or "was SwiftUI poorly designed if it is trying to create new parts of the language out of thin air to support itself?" or "has Swift prioritized the wrong set of features?"

Re:Swift System Is Now Open Source by auggierose on Saturday September 26, 2020 @09:46AM (#24598817)
Yup, guard statements are indeed great. I am using them all the time. They say more than an if statement, they "guard" the rest of the code that comes afterwards. And especially "guard let" is super useful.

It's ok for you not to like Swift, though. After all, taste is subjective.

Re:Swift System Is Now Open Source by wfbarks on Sunday September 27, 2020 @03:45AM (#24604977)
The versioning issues have improved significantly as the language has matured.