Settings

Theme

A deep dive into Swift’s function builders

swiftbysundell.com

64 points by taksintikk 5 years ago · 38 comments

Reader

jgauth 5 years ago

Great article. As someone new to Swift and SwiftUI, the lack of official documentation around these function builders is frustrating. The best I could find was a draft proposal [1].

[1]: https://github.com/apple/swift-evolution/blob/9992cf3c11c2d5...

setr 5 years ago

I don't understand the necessity for BuildIf/BuildEither -- what could you possibly want to inject into a control-flow construct during initialization?

  • jumhyn 5 years ago

    From what I understand, SwiftUI uses this so that each "snapshot" of the View tree generated by the app can be intelligently diffed against future snapshots. This helps make rendering more efficient, as well as with things like animations. Consider a simple view like:

      var body: some View {
        if someStateBool {
          Text("True")
        } else {
          Text("False")
      }
    
    Suppose that initially, `someStateBool ` evaluates to `true`, and then is updated to `false` (triggering an update. If the control flow were "flattened" (i.e., without `buildEither`), the two snapshots would look like:

      1. Text("True")
      2. Text("False")
    
    The algorithm wouldn't be able to tell the difference between "same view with different string" and "different view entirely". With `buildEither`, the snapshots end up looking more like:

      1. ConditionalContent(first: Text("True"))
      2. ConditionalContent(second: Text("False"))
    
    Now, the update algorithm can determine that the entire view was swapped out for another on the update, rather than just changing the text.
    • ridiculous_fish 5 years ago

      It's more fundamental than that. Consider:

          var body : some View {
             if something {
                return Image("hi")
             } else {
               return Text("hi")
             }
          }
      
      this function won't even compile because Swift infers different types for the returns (Image vs Text).

      In order to give the return value a type, the if statement has to be encoded in the type system itself.

      • jumhyn 5 years ago

        That problem could have been resolved via type erasure (either via `AnyView`, or, if SwiftUI had been designed differently, by having the `body` property be of type `View` rather than `some View`). In fact, opaque types (a la `some View`) were motivated by SwiftUI so that the type information could be preserved to enable the necessary optimizations/animations, without requiring users/library authors to write out/expose the complex type signatures that can arise from even simple view hierarchies.

        Incidentally, if you use `AnyView` liberally you’ll likely see worse automatic animations and degraded performance [ETA: the “degraded performance” claim here appears to have been debunked—see the link below for more info!].

        • LeoNatan25 5 years ago

          Despite what is claimed about AnyView, this has for the most part been proven wrong. AnyView is just as fast, if not faster.

          https://nalexn.github.io/anyview-vs-group/

          In fact, Apple themselves use AnyView internally for many of their controller presentations (such as sheets and pushed controllers).

  • ridiculous_fish 5 years ago

    A SwiftUI view is a function which returns a strongly-typed value. Strongly-typed here is stronger than you may be familiar with, it's like `View<HStack<Button, Slider, TextField>>`. The whole view hierarchy has some type.

    You don't have to write these types because Swift can infer them. But when you write a view, you're really also stitching together a type. This explains some of the weird-feeling limitations, like no more than 10 subviews - since every possible count needs its own separate generic function! [1]

    Anyways the control flow constructs are needed so it can be encoded in the type. You need a way to say "I can be this type, or that type" at the type level - that's what _ConditionalContent encodes. Not a SwiftUI expert but that's my understanding.

    1: https://developer.apple.com/documentation/swiftui/viewbuilde...

  • rudedogg 5 years ago

    Not sure if I'm missing something, but under the "Conditionals" heading there is an example.

    I've been writing a lot of SwiftUI code since it came out - and a common use is like that example. Imagine a settings UI where you want to only show an advanced option if a switch/checkbox is toggled.

    • setr 5 years ago

      The example of...

          static func buildIf(_ value: SettingsConvertible?) -> SettingsConvertible {
              value ?? []
          }
      
      and

          static func buildEither(first: SettingsConvertible) -> SettingsConvertible {
              first
          }
      
          static func buildEither(second: SettingsConvertible) -> SettingsConvertible {
              second
          }
      
      ?

      These just return their values -- the only one of note is that buildIf returns the empty array by default, but otherwise this is just defining an if statement to be an if statement.

      It gives you however to make an if statement do something other than being an if statement, and that seems... bad.

      You could for example define it as

          static func buildEither(first: SettingsConvertible) -> SettingsConvertible {
              []
          }
          static func buildEither(second: SettingsConvertible) -> SettingsConvertible {
              []
          }
  • dwaite 5 years ago

    In other languages, the builder pattern usually consists of just methods on a builder object that manipulate internal state until you 'build' an instance. Function builders on the other hand support building of a strong type.

    The builder can convert expressions into components that are then assembled into results. Some applications want to be able to represent the result as a strong generic type.

    As an example of this, imagine

      if let releaseName = releaseName {
         Div("Release \(releaseName)")
      else {
         Blink("Prerelease")
      }
    
    might be captured by such a builder as an Either<Div, Blink>.
  • rmrfrmrf 5 years ago

    type of device (iPhone, iPad, etc)

herodotus 5 years ago

I enjoy articles like this. And I am spending a fair amount of my retirement time writing Swift. In fact I have written a reasonably complex MacOS App in Swift, and it works well. (For the 15 or so years I worked at Apple everything I wrote was in Objective-C or C). But Swift has what one of my friends calls "a high surface area". In spite of using Swift almost daily, I have to say that if someone asked me "Do you know how to program in Swift" I would have to honestly answer "No."

carlhung 5 years ago

What is the use case except swiftUI?

LeoNatan25 5 years ago

I must have a different idea of what “deep dive” means; this is simply going through the (relatively simple) motions of implementing a builder. “Deep dive”, to me, would look at how the compiler translates statements using these builders, for example, or reverse-engineering Apple’s builders for juicy information.

I’ve recently forayed into SwiftUI to see what all the fuss was. I have to say, I really feel for people just now starting to learn app development. Older Cocoa and iOS developers probably remember what actual in-depth articles look like, what “deep dives” actually are, etc. Instead, what we have is a culture of very shallow and information-light “articles”, that seems to me more like SEO bot posts trolling for clicks, rather than written for developers, by developers. And it’s not like the Sundells and Hudsons, but also NSHipster, CocoaWithLove, etc., which were traditionally where high-quality and information-rich content would come from in the past. Likewise with conferences, whereas in the past they’d invite developers to “deep dive” into and interesting development or debugging session, now they’ve devolved, for the most part, into these shallow, byte-sized “Swift” nonsenses. As if the language somehow defines the identity of the developers, and apps magically become much better as virtue of the language used, rather than the system frameworks.

I’m getting old.

  • chmaynard 5 years ago

    There are some great examples of this type of in-depth analysis in Mike Ash's blog:

    https://mikeash.com/pyblog/

    • LeoNatan25 5 years ago

      Yes! But where is he today? Working at Apple, barred from posting on the blog.

      • chmaynard 5 years ago

        What evidence do you have that he left Plausible Labs to work for Apple? If true, that could explain why his blog has been inactive.

        • mayoff 5 years ago

          https://twitter.com/mikeash/status/943890969879023618?lang=e...

          > mikeash @mikeash · Dec 21, 2017

          > Huge news! I’ll be joining Apple in January to work on the ObjC and Swift runtimes. It’s an amazing chance to work on stuff I’ve tinkered with for years. Friday Q&A will continue, although it might be a bit slower while I get into the swing of things.

          • chmaynard 5 years ago

            Hey Mike, it's time to write another blog post about some of the cool stuff you've been working on at Apple. Swift is open source so confidentiality shouldn't be a problem -- right?

  • swiley 5 years ago

    I think part of the issue is that there are fewer and fewer people who are both apple enthusiasts and have been apple developers for a long time.

    Up until snow leopard lots of very old APIs had been kept around so actually pulling things apart was not only an interesting thing to do but even profitable (because the knowledge gained would be useful for years.) Contrast Apple's current generation of operating systems where the API churn is comparable to lots of JS frameworks. Not to mention how unfriendly the company has been to smaller developers

  • tsycho 5 years ago

    The funny part is that Sundell and Hacking With Swift are actually among the more useful sites, offering bite sized information that you would expect Apple documentation to provide.

    But Apple's documentation nowadays, is so bad (inconsistently so, some parts are fine) that these sites are filling the gap.

    Further, for most other languages, Stack Overflow fits this need mostly fine. But Swift and SwiftUI have been changed so often that the accepted answer on Stack Overflow becomes outdated within a year.

  • Austin_Conlon 5 years ago

    One YouTube channel that I think deserves more recognition for in-depth content is AppleProgramming. Here's a video from him on reverse engineering Cocoa controls: https://www.youtube.com/watch?v=PTCKXTPUeqY&list=PLgTh9sDnKC....

  • transfire 5 years ago

    > I'm getting old

    And wiser.

    Youth is wasted on the young. Unfortunately for the field of software development that means endless gyrations of over engineering and technobabel.

  • luigi23 5 years ago

    I feel you, but the ‘deep dive’ that you mentioned is not a reserved phrase onlh for super detailed, reverse-engineering articles. Nowadays it’s more and more difficult to find them since writing such article takes 10x of the time compared to standard one, and audience won’t grow, or even shrink(due to complexity and non practicality). I really like them though, especially when they’re written on some niche jekyll blog with atrocious layout - you can feel that it’s been written by a passionate.

  • jdmoreira 5 years ago

    I'm not disagreeing with you but I want to come here in defence of John Sundell as an excellent Swift programmer that is releasing amazing open source code.

    I don't consume his content (neither his website nor his podcast) but he sure knows his Swift. His recent code is probably some of the best Swift code I've seen and I have very high standards for that.

    He creates amazing DSLs / abstractions / APIs by leveraging the type system which in my opinion is exactly what Swift should be about.

  • patriotapclypse 5 years ago

    If you want actual in-depth articles, SwiftRocks has some good ones. For example: https://swiftrocks.com/how-never-works-internally-in-swift

    I also share this opinion. This hard-on that companies have of making coding easy for everyone will be the field's downfall. Just look how people are outraged whenever algorithm's are mentioned in interviews. I lost track of how many people with "senior" positions coming to interview at my company and showing that they know absolutely nothing about anything. My explanation for this is that you have a bunch of people from other areas coming to tech simply because it's easy money. They don't care about becoming the next legendary developer or something like that, they just wanna make easy money. The result is that everything gets dumbed down as a result. I really hate this and it probably means that a lot of important knowledge will be lost when the old dogs die.

    • LeoNatan25 5 years ago

      That was a good article, thank you! Exactly what I expected from this “deep dive”.

  • Benjammer 5 years ago

    Two reasons for these shallow, high-level-walk-through type of articles that I've seen are to pad a resume or to pad a promotion packet.

    • LeoNatan25 5 years ago

      Sure, this is a problem in general when companies require or “heavily encourage” its engineering to post “blogs”. And some developers are just not writers, or lack the skill to do proper articles.

      But, here, this is not the case; the author makes their living from this. With the former engineers, that’s excusable. Here, less so.

  • Grustaf 5 years ago

    There is a lot of deep material on SwiftUI, for example https:// swiftwithmajid.com and https://swiftui-lab.com. The latest edition of the excellent Stanford course also uses SwiftUI, and the tutorials by Apple are great.

    • LeoNatan25 5 years ago

      That’s not “deep”. That’s just following the motions to accomplish basic tasks.

  • heavyset_go 5 years ago

    > I’m getting old.

    I think you hit the nail on the head with this observation:

    > Instead, what we have is a culture of very shallow and information-light “articles”, that seems to me more like SEO bot posts trolling for clicks, rather than written for developers, by developers.

    For a while now, content's been created as a means to improve SEO, and it's really obvious when an article was written just so it contains the right mashup of keywords and that it's padded to just the right length.

  • auggierose 5 years ago

    It's not that bad, I've stumbled across that particular article just 1 or 2 weeks ago because I wanted to check what kind of functionality of function builders I can use now for my DSL. It's probably more illuminating though to just try out for yourself... For example, while the article mentions "if let", does that mean "let" also works now?

    And yes, I wish Apple had proper and up-to-date information on this somewhere.

  • Austin_Conlon 5 years ago

    I'm surprised to see NSHipster included in your criticism, can you elaborate or point to some articles for comparison?

    • LeoNatan25 5 years ago

      NSHipster was about taking a piece of obscure framework and deconstructing in as much detail as possible. Now it’s about “DSL”s, Swift, Swift, Swift and some more Swift.

  • adamnemecek 5 years ago

    > As if the language somehow defines the identity of the developers, and apps magically become much better as virtue of the language used, rather than the system frameworks.

    Language matters just as much as the frameworks.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection