
SwiftUI Defaults Considered Harmful - Aqua_Geek
https://tonsky.me/blog/swiftui/
======
saagarjha
SwiftUI has defaults because nobody knew what UIKit's were supposed to be.
Some of them were fiddly secret layout guides in Interface Builder, and some
were accessed through the magic "-" in a VFL constraint, but overall it was
very difficult to actually know how much spacing things _should_ have. And on
Apple's platforms, this matters: users know what things should look like, and
if you're off you just look out of place. And if they change in the future,
which they have on occasion due to new iOS versions or hardware (iPhone X,
anyone?) you might end up off even if you didn't change anything in your code.

SwiftUI _intentionally_ abstracts all of these things away from you so you
don't have to deal with it, or even know about it. You're used to programming
on the web? Well, the web has no standard. And anyways, people looking for
magic defaults is how "8" and "44" show up seemingly randomly in iOS apps. Let
the system decide for you…if you _really_ need to override it, you can add
your own explicit value.

~~~
nwienert
Yea, well said. There are some awkward bits, but if I were writing an article
on my first 4 months with SwiftUI it would look totally different.

There are tons of bugs, random issues, and a lack of controllable properties
in areas. There’s a lack of documentation, performance, etc.

But the language, defaults, components? All wonderfully done.

In fact I’d spend years building a UI kit in React attempting to standardize
on things like that, and on seeing and using SwiftUI I was constantly
impressed by how well done it all feels when the language (Swift) is robust
and designed to work alongside the framework.

Count me as basically optimistic, just hoping they iron out all the beta-y
aspects quick!

------
013a
There are definitely a few things it does that are weird, and this article
hits on a few of them.

But, I'll call special attention to the whole "adaptive padding thing" as a
broader signal for something I feel that SwiftUI does very, very right and
more UI frameworks need to start thinking about. Its made to design iOS apps.
iOS has a design language that (1) is relatively consistent, (2) changes over
time, and (3) changes across the many devices Apple supports.

In this era of many, many devices (don't just think Apple here; think any
device; think VR, think TVs, etc), we need to operate at a higher layer of
abstraction than most UI systems operate at. Most websites are pure garbage on
35" ultra-ultra-wide displays. It took a decade before mobile web entered the
"generally useable" state it is in today. Ever tried to enable an ultra-high
DPI setting on, say, Ubuntu or Windows?

All of these are getting better, but they only get better because the
underlying technologies are becoming more generic.

> If I forgot to put padding between HStack elements, well, shame on me, there
> should be no padding! All mistakes are mine.

Wrong, and Apple has the data to prove it. When you release a poorly designed
app to the App Store, the mistake is your's; your customers suffer because of
it; and, it hurts the optics of application quality on the App Store, and thus
Apple suffers.

This is relatively easy to draw a comparison to, say, manual memory management
in C++. "If I forgot to properly bounds check a memory segment, well, shame on
me, there should be no bounds checking! All mistakes are mine". Sure; and now
your customers are vulnerable to hackers. You have a higher responsibility
than just your Pride.

The defaults should be Safe. There should be options to override them when I
feel confident I know what I'm doing (and SwiftUI has this, not the least of
which being, you don't have to use SwiftUI, you can mix-and-match SwiftUI
components with traditional iOS components).

~~~
diffeomorphism
Haven't we been going in the other direction in recent years?

With integrated title bars in browsers, custom css, fonts etc.. Chrome on
Windows, Mac, Linux etc. always looks like chrome but not native. Similarly
webpages look "exactly like the designer intended" even if it is a very bad
fit for your device.

We used to do things generically, but changed to prescribing every little
detail and this now breaks when our assumptions change.

~~~
013a
We did use to do things generically, but more-or-less the wrong kind of
generic.

Android is a great example of this. I don't know how things are done now, but
for its first few years, they had screen size classifiers; ldpi (low dpi),
mdpi, hdpi, etc.

Of course, devices got better. That set grew to ldpi, mdpi, hdpi, xhdpi,
xxhpdi, and xxxhdpi. There's also tvdpi for televisions.

It was supposed to be generic. It became a mess, because they were operating
at the wrong level of abstraction. But whats more; in the beginning, the `dpi`
of a device was actually a consistent way to determine the screen size! I saw
many apps in the day rely on this; they'd change the text sizes and paddings
and even high level UI organization upon render by conditionally checking the
dpi of the device. Its generic, right? Its not like I'm saying "if screen
width is above 750px, render X" (cough css).

I know less about android as we approach closer to today, but I'm familiar
with another problem they had concerning foldables. Android apps were never
designed, from the start, to be able to respond to changes in screen size! So
that required some new frameworks to be put in place, and old apps had to
update.

Point being; our UIs have gotten more complex, because the problems they're
solving have gotten more complex. We had HTML; a truly pure form of "generic
UI design". But, it was designed for documents, not applications, so we built
CSS and JS and wrote ourselves into the mess we're in today. Android had some
ideas around generic UIs, but they too did not predict what people would
actually be using their platform for and where technology was going.

SwiftUI is another stab at this, and maybe they'll get it right. I don't know.
But, I think technology is settling a bit, and with that settling comes a
greater understanding of what UI designers need from their frameworks.

~~~
kllrnohj
> Android is a great example of this. I don't know how things are done now,
> but for its first few years, they had screen size classifiers; ldpi (low
> dpi), mdpi, hdpi, etc.

This example doesn't really work. Those buckets have always been primarily for
image asset selection, not UI declaration/layout. It's comparable to the 1x,
2x, 3x that exists in iOS land.

Nothing has ever actually replaced those. In any UI toolkit. Vector assets
finally took a chunk out of their usage, but there's still plenty of assets
that are not vectors.

The density support in Android largely remains the gold standard. The only UI
toolkit that actually achieved robust density independence. There's plenty
broken about Android's UI toolkit, just this isn't one of them.

~~~
013a
Yeah, that was a misprint on my part; I should have referred to them as
density classifiers, which is what they are. My brain got jumbled because my
broader point came later on, in how there was a time years ago when many apps
were elying on them as a signal for screen size, to the point where I saw apps
place layout files in a specific mdpi or xxhdpi folder.

Of course, today, I'm sure the Android landscape is more mature and different;
I have less context about the thinking around a modern android app today.

------
kenforthewin
This website's background color is considered harmful, and "considered
harmful" essays are considered harmful.

~~~
oefrha
Site is also non-responsive with <meta name="viewport" content="width=640" />,
looks horrifying on the 12.9’’ iPad Pro even without taking color scheme into
account. I know complaining about blog design is out of scope, but if @tonsky
is reading this thread, please consider fixing your meta viewport tag.

~~~
saagarjha
> I hope you have a wide enough monitor to read this.

Perhaps they're merely unaware of how their website looks?

~~~
madeofpalk
Yeah, I did think it was amusing reading that on my 27" 2550px wide monitor
monitor that the site formatted it so narrowly.
[https://i.imgur.com/VG31Kpj.png](https://i.imgur.com/VG31Kpj.png)

~~~
Fauntleroy
For body copy that line length is pretty much ideal (for readability), but the
code blocks could definitely benefit from being as wide as possible...

~~~
madeofpalk
Yeah, the reading experience was pretty comfortable. Just thought it was
amusing that the author hoped I had a big monitor when the author constrains
the code blocks to such a narrow width.

------
ken
Just when I thought Lisp had been ransacked for every last feature that
language designers were willing to steal, the "War on commas" pops up --
complete with discussion of the essential differences might exist between "("
and "{", the pain of needing another way to say "if", and the lack of support
for the rest of the language.

And the last couple interesting Swift libraries I saw had .gyb files and #if
directives.

Apple tried _really hard_ to make a fully static language that was visually
elegant (and looked like C), but in the end we need so many dynamic features
that what we ended up with seems much more complex than just having had well-
designed macros from the start.

The cynic in me suspects that they know this would be worse, but has the
advantage that only Apple can add such features, not the common programmer.
OTOH, the cynic in me knows that staying far away from Lisp is par for the
course, and every new language needs their code to look like an example from
the designer's tattered copy of "K&R".

At least they managed to drop C-style for-loops in a mainstream language, so
next time a company decides to design a new language, we can hopefully start
there. I predict we're about 3 generations of corporate languages away from
seeing macros get "invented" again.

~~~
alehander42
many modern languages have macros: rust, crystal, elixir, nim not very
corporate though, but getting there? with rust(mozilla a bit and others)

~~~
pjmlp
Java and .NET languages also have them, although a bit cumbersome via
attributes, compiler plugins and on .NET's case, expression trees.

------
jmull
I really don't think this is a good criticism of SwiftUI.

The author is confused about the whole approach to SwiftUI and spends a lot of
words complaining about issues arising out of that confusion. E.g., SwiftUI
doesn't use Swift's DSL capability to avoid commas. It uses it to have a
declarative DSL integrated into Swift programs. You could argue about the
entire approach, but instead the author complains about commas and ifs. The
things about the ifs and other potential control flow constructs makes it
clear that the author doesn't get what a declarative approach really means.

Likewise, the section about "wraps" where the author feels the SwiftUI API is
inconsistent because stacks "wrap" and padding "wraps" so they should use the
same syntax. But I think that's just a misunderstanding of the author's.
"wrapping" isn't a fundamental concept of SwiftUI so there's no particular
reason for the API to be organized around it. (I would say stacks arrange a
list of views and padding pads a view. Also, bold() operates on Text and
returns Text because Text holds styled text and bolded Text is still Text.
padding operates on any View and returns some View. The types flow naturally
from the problem domain, so that's good.)

Also the conclusion: "The solution…is to be dumb and explicit!" That's really
asking for a completely different framework. It seems a little off to
criticism SwiftUI for not being what it was never intended to be.

I think there is good criticism in here, though. SwiftUI introduces a LOT of
patterns, concepts, many of which will not already be familiar to many
developers. It's concise and reads pretty intuitively, but many developers
won't get far before hitting a lot of new stuff... that means steep learning
curves and confusion, like the author. I don't know if that makes it bad, but
it's certainly anyone consider using it needs to be aware of.

~~~
dmitriid
The author is also the author of Clojure/script libraries Rum snd Datascript.
He knows what declarative means very well.

Swift UI creates a mess of special cases pretending to be declarative, and
does a poor job of it.

~~~
jmull
He's suggesting he ought to be able to use imperative Swift control flow
constructs in the declarative SwiftUI DSL. I suppose I can't really know
exactly what his confusion is, but that just doesn't make sense.

~~~
dmitriid
It does make sense. Because SwiftUI creates special constructs for regular
language features (if, foreach) despite those features, you know, being
available in the language.

~~~
jmull
It doesn’t make sense because SwiftUI is a declarative language. I understand
the confusion, since it uses Swift’s DSL feature and is tightly integrated
with Swift, but it is distinct and has it’s own design that isn’t directly
compatible with Swift’s imperative control flow constructs.

Now, you can argue that Apple should have created a new imperative Swift-
integrated UI framework, and if they had, it would be a good criticism if all
the normal Swift control-flow mechanisms weren’t available natively. But the
author and you aren’t objecting to SwiftUI’s declarative nature.

BTW, If you manage to map all the kinds of loops, breaks, etc, into SwiftUI it
isn’t declarative anymore. You’ve managed to go back from describing the UI in
terms of “what” (declarative) to “how” (imperative).

Since the author expresses approval of the declarative nature of SwiftUI and
complains about it, I know he’s confused.

~~~
dmitriid
No. I, and the author, argue that _nothing_ prevents Swift from having
declarative foreach/if.

SwiftUI _already_ introduces severely underdesigned awkward structures to
replicate _existing_ behavior, and it _shouldn 't_.

SwiftUI's ForEach and If are ugly unnecessary hacks that replicate existing
behavior and raise the question: why aren't other constructs there?

------
sleepinseattle
I’m guessing the magic layout things are intentional because SwiftUI is
designed to make it easy to have one app feel native on iPhone, iPad, Apple
Watch, Mac and AppleTV, which all have their own design language and
ergonomics.

As long as it provides ways to override defaults and take full control where
needed, this seems reasonable. I’m guessing you can drop a Metal view into
your SwiftUI app, so quit complaining :)

~~~
jamil7
Exactly, if you just want to bang something out that looks like an "apple app"
across all those devices I think the auto spacing and sizing stuff works
pretty well. You can always tighten it up and override it later.

------
erikrothoff
I was really excited about SwiftUI after having done a lot of React
development recently. The declarative style is so much nicer than the
MVC/procedural code that regular UIKit code becomes.

After 30 minutes of updating Xcode I was able to start writing SwiftUI code.
Then another 2 hours upgrading our Swift project to the latest version of
Swift. I googled for documentation, found barely anything and the code samples
on developer.apple.com were already outdated. I finally got something up and
running, but _nothing_ in the semantics worked as expected. Getting a button
to render nicely was insanely complex (which view should have the background
color? font? trying different things didn't work at all). Oh and recompiling
took a minimum of 30 seconds each time.

All this prompted me to finally give react-native a try. In under 15 minutes I
had a working example. After making a change I saved the file, alt-tabbed to
the simulator and the changes were already applied. And it works instantly on
Android, I can try it out on my phone using expo without any hassle.

I just can't comprehend if and how Apple will catch up with that experience?

~~~
kenshi
I suspect Apple knows the developer experience for Swift is terrible (even if
the Apple developer community at large is in mass denial about this).

The number 2 item on Swift Core Teams goals for Swift 6 is "Create a fantastic
development experience". See: [https://forums.swift.org/t/on-the-road-to-
swift-6/32862](https://forums.swift.org/t/on-the-road-to-swift-6/32862)

Whether anyone at Apple cares about documentation any more is another matter.
A really sad state of affairs, because once upon a time, Apple had some of the
best documentation out there. Of course, that was when they actively needed to
court a developer community, and couldn't just announce something half-baked
at WWDC and get mass adoption from enthusiastic developers.

~~~
jamil7
I don't know, maybe some of the die hards are in denial. I really enjoy the
language and the platforms but I'd readily admit it's pretty far behind in
terms of DX. I think at this point Apple is going to have to make this a
really big priority if they want to remain relevant and it's going to take a
lot of effort on their part.

~~~
chipotle_coyote
While I certainly can't speak for all diehards, I hear a lot of complaints
about the state of Apple's documentation from long-time developers these days.
(In my experience, the true Apple diehards are often _very_ critical of the
company, but they tend to have specific trenchant critiques.)

------
rkapsoro
While I don't yet have great confidence in my mental model of SwiftUI's type
system, my understanding is that the DSL builders exist for more reasons than
just to eliminate commas.

The new Function Builder and `some` return type features of Swift allow you to
return a complex, nested type describing not just that it's a View but rather
also all the structure within.

This means that at _runtime_ you can have a (non-erased!) type describing the
contents of your `var body` like this:

    
    
        Button<Group<_ConditionalContent<Text, Image>>>
    

This particular body displays a Text if a state boolean is true, and an image
if not.

Super interesting - and having types this descriptive can potentially enable a
host of interesting features and optimizations. For example, across
evaluations of your UI SwiftUI needs to track the identity (and location in
your view graph) of all of your views, in order to keep their state, bindings,
and other stuff that needs to remain consistent across time. The position if
your view in a type hierarchy is the default way SwiftUI does so. This starts
to blur the line between code and the type system, which I think the
Functional Programming folks have been exploring for years.

One more nitpick: the use of View Modifiers on children noticed by parents
(like the `navigationBarTitle` example he uses (as discussed in the "Child
Privacy Invasion" section), is to allow for children to specify metadata that
the parent might care about. This is actually pretty nice, because then you
can nicely compose together the various parts of your app without having to
spread around the configuration for your tab bars and such (which is a bit
messy in UIKit).

edit: formatting. I always trip up with it on HN due to the lack of a Preview
feature.

~~~
K0nserv
> One more nitpick: the use of View Modifiers on children noticed by parents
> (like the `navigationBarTitle` example he uses (as discussed in the "Child
> Privacy Invasion" section), is to allow for children to specify metadata
> that the parent might care about. This is actually pretty nice, because then
> you can nicely compose together the various parts of your app without having
> to spread around the configuration for your tab bars and such (which is a
> bit messy in UIKit).

I wouldn't say it's too messy in UIKit but I agree with the motivation. To add
some more context here's how you configure the title of the navigation bar in
UIKit

    
    
        navigationItem.title = "My Title"
        navigationItem.largeTitleDisplayMode = .always
    

This does not happen in the class that renders the navigation
bar(UINavigationController) nor does it happen in the navigation bar view
itself(UINavigationBar) it happens in the view controller that is currently on
screen and is the "active" child of UINavigationController.

------
bouke
Observing the launch of SwiftUI as a bystander (I'm not developing for any
Apple platform), it seems that people are very excited about SwiftUI, but also
get burned by it a lot. This is mostly Apple's fault by releasing this
framework without any caveats. But the framework is more like an early alpha,
not to be used in production. Tooling is not yet ready, documentation is not
yet ready, heck even Swift –the language and compiler– aren't even ready yet.
Apple should've put a big warning notice on any SwiftUI related website to set
the correct expectations.

~~~
jamil7
I agree for the most part however I have put a simple app in the store with it
and it works fine, it's usable for small apps. I had to wrap a few UIKit
elements and a few other workarounds that I can't think of right now. But
overall I'm happy they released it early and can benefit from the communities
feedback and usage rather than building the whole thing in secret and
releasing something finished that we might not even want. I hope that this is
the beginning of them improving DX on their platforms as they have a lot of
catching up to do to be competitive with other platforms.

~~~
cerberusss
Yeah, my sentiments exactly. I'm in the process of finishing a small app for a
client, and it's been a blast. As you said, a number of workarounds are
necessary due to the fact that UIKit is so rich, and SwiftUI is rather sparse
at the moment.

However the fact that it's so easy to build new UI components, at this phase
partly makes up for it.

------
0xferruccio
I tried out SwiftUI a couple of months ago and it was buggy even when sticking
to the standard Navigation components..

But now it seems like a lot of problems have been solved

[https://stackoverflow.com/questions/59279176/navigationlink-...](https://stackoverflow.com/questions/59279176/navigationlink-
works-only-for-once)

~~~
saagarjha
> even when sticking to the standard Navigation components.

The standard navigation components have _always_ been the buggiest part of
UIKit. Don't even get me started on how UISearchController and
UINavigationController interact on iOS 13…I have an app that's been sitting on
the back burner, with full dark mode support, but unreleased for over six
months because I haven't taken the time to figure out why the search bar
decides it wants to be _above_ the large title.

~~~
0xferruccio
Didn’t know this! Am very much an amateur with iOS development and thought
that sticking with the Swift “happy path” would’ve been a good idea

~~~
saagarjha
It's gotten better, it will probably work if you're not doing anything
complicated. My view is set up from a five-year old storyboard and is dual
UINavigationViews with UISearchControllers inside a UISplitView inside a
UITabViewController :/ I'd still suggest sticking to the happy path, the other
ones are even worse…

------
GeneralTspoon
> Some things are probably just plain mistakes (very funny though). E.g.
> NavigationView takes its properties not from its constructor or via
> modifiers, but instead from the properties of its first child. WHY?

This sounds like it's just inheriting the default iOS behaviour? The current
ViewController sets the Navigation View's properties.

I haven't touched SwiftUI yet, but I'd imagine the existing
NavigationController setup still exists within the SwiftUI framework, and this
weirdness exists due to legacy reasons essentially.

------
madeofpalk
Reading through the syntax changes they made makes me really appreciate the
decisions made around JSX and how that works, syntactically. It's _just
javascript_ , and none of these weird constructs need to be added into some
DSL to support it. There's the reasonably minimal html-ish syntax, then
"escape to javascript" to add in conditionals or loops or whatever.

I wonder if there was (or still is) a way to do something similar for Swift
and SwiftUI.

~~~
thu2111
Surely JSX is ... well it's something that looks a lot like XML, hence the
name. It's not just JavaScript, is it? It's pretty much the definition of
embedding a DSL.

I've not used SwiftUI but I've used TornadoFX which is similar, but with
Kotlin instead of Swift. There's no weird syntax or DSLs (even though they
call it that). It's all just functions and lambdas, so the language is always
there and the syntax is always consistent with what you use elsewhere. It's
not like React/JSX where UI code syntactically looks different.

~~~
madeofpalk
JSX is 'just' an XML-like syntactic sugar for making nesting function calls
nicer in Javascript. Yes, its a DSL, but it keeps the "domain" extremely small
and it transpiles in a very straightforward way down plain javascript

    
    
        <Container>
          <Text weight="bold">madeofpalk</Text>
          <Image src={profilePic} />
        </Container>
        
        // is syntactic sugar for
        React.createElement(Container, null,
          React.createElement(Text, { weight: "bold" }, "madeofpalk"),
          React.createElement(Image, { src: profilePic })
        );
    

Whenever you need 'logic', you just escape out to javascript with braces

    
    
        <Container>
          { isVerified ? <Tick /> : null }
          <Text weight="bold">madeofpalk</Text>
          <Image src={profilePic} />
        </Container>
    

JSX has no conditional syntax, no ternaries or any extra constructs apart from
how to nest children. This is I think a simplicity that would have been nicer
to see in SwiftUI.

~~~
thu2111
I guess I'm not sure why this is better than the Kotlin/Tornado/SwiftUI
approach of allowing you to move a lambda in the last parameter visually out
of the function. So:

    
    
        container {
            text(weight = "bold") { "madeofpalk" }
            image(src = profilePic)
        }
    

It seems more logical and consistent with the rest of the language. The only
reason for the HTML-like syntax is JavaScript's tight connection to the web,
after all.

~~~
madeofpalk
I apologise for not being clear, but the point I'm trying to make is not
around the angle bracket syntax, but with how light the DSL is and for any
sort of logic syntax, you just escape back to Javascript.

JSX does not have conditionals or loops in its syntax. SwiftUI does.

------
jiofih
This is a very myopic view of UI development. The library is built to give you
sane, well designed defaults that is lay together well when following the HIG,
and which you should rarely attempt to override. Case in point, HStack, whose
sole purpose is to _stack items horizontally with proper spacing_ and is quite
hard to achieve correctly on the web. If you want “dumb and explicit” why use
a UI kit?

------
TuringTest
_> When fixing broken layout, it is always easier to add stuff that you forgot
than removing stuff that your framework did for you and you that can’t see._

This paragraph reminded me of this old Jargon File koan:

\---

In the days when Sussman was a novice, Minsky once came to him as he sat
hacking at the PDP-6.

 _“What are you doing?”_ , asked Minsky.

 _“I am training a randomly wired neural net to play Tic-Tac-Toe”_ Sussman
replied.

 _“Why is the net wired randomly?”_ , asked Minsky.

 _“I do not want it to have any preconceptions of how to play”_ , Sussman
said.

Minsky then shut his eyes.

 _“Why do you close your eyes?”_ , Sussman asked his teacher.

 _“So that the room will be empty.”_

At that moment, Sussman was enlightened.

~~~
Izkata
I've never understood this one. Initialized randomly and then trained is
accurate; Minsky is the one who comes off as ignorant, when the last line is
supposed to indicate the opposite.

~~~
TuringTest
That's not ignorant on his part, it's just a silly analogy to get the point
across; and I think you're missing the point by thinking of what happens
_after_ the network is trained; the point made is about the _initial_ state of
the network, not the outcome.

The neural network will have preconceptions on how to play no matter how, even
if you wire them randomly; the difference of making them random is that you'll
have no idea what those preconceptions are, not that they don't exist. The
original story on which the koan is based might make it clearer.

[1]
[https://simple.wikipedia.org/wiki/Hacker_koan#Uncarved_block](https://simple.wikipedia.org/wiki/Hacker_koan#Uncarved_block)

If you still want this to be about the final state, the point would be that,
if the training process works well, it shouldn't make any difference whether
the net was wired randomly or orderly.

------
qubex
The “X considered harmful” trope for deliberately strident technical screeds
that quibble about what are mainly niche concerns has tired me out.

“‘X considered harmful’ considered harmful”, I guess.

~~~
blowski
You’re going to love this essay by Eric Meyers.

[https://meyerweb.com/eric/comment/chech.html](https://meyerweb.com/eric/comment/chech.html)

Now I await “Comments linking to the ‘considered harmful essays considered
harmful’ essay on ‘x considered harmful’ discussions considered harmful”.

------
rubyn00bie
I think everything after the first gripe is a fair point, but I don't get what
the problem is with the first code chunks... it seems like the author is
saying "this is weird to me, and I don't like that," but I have no idea how
else it'd work properly.

For example, explicitly defining out function arguments is exactly what Scala
does for function, check out this bad mofo, defining a function with 22
arguments (that I fell in love with years ago): [https://www.scala-
lang.org/api/current/scala/Function22.html](https://www.scala-
lang.org/api/current/scala/Function22.html)

Why'd I fall in love with it? Because it makes sense, that's how it should
work right? I don't see how defining out 10 items explicitly; so, that each
can have it's own type, is a problem. It's pretty damn nice they did it out to
ten arguments, if you want more, extend the object... /shrug

If you used a list instead, e.g. `T[A]` you'd take a hot-fat erasure-shit on
the type information of each item in the list (or at least you would last time
I used Swift extensively)... this way you keep that type information around.

P.S. To be honest, explicitly defining things out like that can give you HUGE
wins in languages like Swift because you give the compiler so much more
information. It just doesn't usually pop onto most folks radar because it
looks obtuse... with most modern code editors though it's easy enough to write
in a couple minutes, if there's no macro system.

------
K0nserv
I really don't agree with most of this post but I do find the function
builder[0] feature that was introduced to support SwiftUI fairly overkill. I
don't fully understand why they didn't use a lighter abstraction based on
arrays and normal return values like React does instead of adding all this
"magic", maybe there's a really good reason that I am not seeing.

All the other "magic" and defaults are excellent ideas because they encode
Apple's Human Interface Guidelines[1] straight into the framework which helps
you create apps for the different Apple platforms that will fit in and feel at
home. With a web or React Native/Flutter/Cordova/... context this might seem
jarring but the whole point is that an app it shouldn't be a completely free
form canvas and the frameworks should make it easy to build a best in class
HIG compliant Apple app.

0: [https://www.swiftbysundell.com/articles/the-
swift-51-feature...](https://www.swiftbysundell.com/articles/the-
swift-51-features-that-power-swiftuis-api/)

1: [https://developer.apple.com/design/human-interface-
guideline...](https://developer.apple.com/design/human-interface-guidelines/)

------
ogre_codes
> I mean, the only difference before the two is whether you have to put a
> comma between elements or not.

Personally, I vastly prefer minimizing punctuation in code. Most punctuation
like this only lends itself to creating places where additional errors and
bugs can creep in. Listing elements on separate lines gives you the separation
needed so it's clear it's a list of things, the comma at the end of the line
is needless.

> All because someone in charge of API design was afraid of lists and had more
> power than someone in charge of Swift language.

I suspect the people in charge of designing the Swift language have a similar
aversion to needless punctuation in the language. They made a point of calling
out the lack of a semi-colon in the original Swift launch announcement. This
isn't some API designer pushing the issue, it's part of the philosophy of the
language.

------
mattste
I recently started a SwiftUI project and this is a very accurate take based on
my experience.

How I spend my time in SwiftUI: 1\. Wondering how I can get some conditional
logic. Coming from React, this is a major issue that needs to be addressed.
2\. Figuring out where and what the error actually is. 3\. Restarting Xcode
for my view to magically start working again.

The two-way data binding is a blessing and a curse. I like React's method of
passing callback functions to keep the state logic separated. This comes up
with me when working with sheets.

I see the potential. I like having an all-in-one experience that IDE +
framework integration provides but the poor defaults and breaking bugs really
make me question the execution.

------
ChrisMarshallNY
I'm in no hurry to start using SwiftUI. I'm giving it another year.

That doesn't mean that I don't like it. I think it's a great idea. It's just
having a hard time clambering out of the bassinet.

~~~
cerberusss
> It's just having a hard time clambering out of the bassinet

What are the reasons for you to have this opinion?

~~~
ChrisMarshallNY
Mostly the limited uptake (I anticipated that), and the maturity of the tools.
I despise IB/Storyboard Editor, but it gives some serious control over a lot
of stuff.

I don’t mind doing programmatic tweaking, but on my machine, at least, I don’t
get very reliable previewing. I have to run the app to get an idea of how my
tweaks are working (to be fair, IBE is similar, but the preview is somewhat
more reliable).

I really want this to work. I’m glad to see KVO getting some love on iOS.

~~~
cerberusss
Limited uptake by developers you mean? How do you determine that?

I had two instances where the preview turned out to be a hassle (crashing, or
hard to get it to work).

First was a test project with Core Data. It was a hassle to set up the
preview. So much so, that I often skipped it.

Second instance was crashing; I'd created a View but the layout was based on
something in UserDefaults, and I forgot about that. So when I created another
view that incorporated that first view, I got crashes. So bad, in fact, that a
restart of Xcode didn't help. I had to close Xcode, then on the commandline,
find and kill the daemon responsible for previews.

Were you able to point to causes of the unreliable previewing in your case?

~~~
ChrisMarshallNY
Aw..heck. I'm not gonna get into back-and-forth.

I will say that I have been developing Apple software for 34 years, so I tend
to be a little on the.."hard-boiled cynic" side.

I have taken OpenDoc and QuickDraw GX classes, because they were "The Next Big
Thing."

I also busted my butt, making sure that my apps were "Copeland-ready" _(Darn
it, now I have to do fifty push-ups)_.

I've learned that it's a good idea to stand back a little, and let the eager
beavers soak up the bullets.

I love Apple (see "34 years," above), but they are absolute Charisma 18 hype
machine masters.

~~~
cerberusss
Leaning towards the careful end of the spectrum, I can respect that.
Especially once you're fast with UIKit, and Auto Layout. And Auto Layout kinda
proves your last point; there's absolutely nothing "auto" about it.

~~~
ChrisMarshallNY
Auto Layout is a nightmare. I won't be sad to see the back of it.

It took me a couple of years to figure out how to use it properly.

Like I said, we're on the right track, and I doubt that Apple will let this
fall by the wayside. I think they were planning this at about the same time
that they started dreaming up Swift.

------
hombre_fatal
> I hope you have a wide enough monitor to read this. Not only does this seem
> ad-hoc and unpretty, but it also doesn’t allow you to put more than 10
> elements in a container! All because someone in charge of API design was
> afraid of lists and had more power than someone in charge of Swift language.

This explanation doesn't sound right to me coming from other statically typed
languages where you're stuck either using codegen or arity hardcoding.
Currying also gives a nice solution where your DSL simply builds up a function
A->B->C->...

Hard-coding each level of arity is done so that your generics keep upstream
type knowledge.

Here's an example in Elm, though it has to keep renaming the function due to
lack of arity overloading.

[https://github.com/elm/json/blob/063aaf05e0dc5a642bacbdaae59...](https://github.com/elm/json/blob/063aaf05e0dc5a642bacbdaae59c33dcfd116898/src/Json/Decode.elm#L420-L450)

You can't use variadic functions because then you function doesn't even know
how many arguments it has at compile time much less any specifics about them.

That Swift doesn't require commas between closure returns seems like a
different point.

You'd still need this solution even if you were just spitting out generic
TupleView<(View, View)>, TupleView<(View, View, View)>, etc.

Unless, of course, you don't actually care about type info the same way you
don't care how many arguments are passed to a variadic max(1, 4, 66) function.

Another comment says there will be a variadic viewbuilder function once Swift
gets variadic generic functions which will still throw away type info, so this
seems to be the case. Still, I don't see the relationship with commas.

------
ericlewis
Just to point something out: his first complaint is over needing to have up to
10 generics, this will be going away with variadic ViewBuilders that should be
coming soon, towards swift 6 perhaps. And will also remove the limit for
number of children. This is mostly a limitation in swift generics, not swiftui
it self

------
layoutIfNeeded
Honestly, just use UIKit. SwiftUI is a bolt-on framework on top of UIKit to
provide a React-like experience for web devs so they won’t rage too much when
Apple inevitably bans ReactNative and Flutter.

~~~
jamil7
SwiftUI is raising the abstraction layer and aiming to provide something much
more productive than what UIKit currently offers. You've framed your comment
as if web developers are cargo-culters who only know how to use React. The web
has already experimented with classic MVC approaches (backbone etc.) and moved
beyond it. Android's Compose is taking a similar approach, as is Flutter which
as far as I can tell is not necessarily aimed at web developers. Also why
would Apple ban React Native and Flutter?

~~~
uwuhn
I don't believe they'll ban it. I do believe they'll increase friction to the
point that it becomes a huge pain to use either for anything but prototyping.

~~~
jamil7
I can't see really why they care that much how the app is written, if it
adhears to the app store guidelines and makes them money then I doubt they're
that interested in banning it or increasing friction. Nearly all the current
top selling iOS games are likely written in Unity and I can't see them banning
that.

~~~
chiefsucker
Platform coherence, but also look & feel come to my mind.

While the guidelines are what the word says, vague guidelines with a lot of
room for interpretation, they don’t necessarily dictate any details. When you
look at it from a more technical point of view, it’s harder to do something
nonconforming with Apple’s frameworks than with 3rd party alternatives.

Games are a different thing. They are more like their own operating system
within iOS and usually have their own quirks (to make them playful).

------
tayistay
Would it be possible to wrap SwiftUI such that we don't have to use that DSL,
don't have that 10 child limit (how many hours wasted figuring that one out?),
and don't have bizarre non-localized error messages?

My guess is the answer is no because SwiftUI builds view hierarchies using
parameterized types, so you're always stuck with `some View` and the
associated complexity.

------
barbecue_sauce
Is SwiftUI only compatible with the newest iOS versions? Will using SwiftUI
mean only people running iOS 13+ can use it?

~~~
saagarjha
Yes.

~~~
epaga
That said, current iOS 13 adoption rate is already at 93%...

~~~
travisgriggs
Citation?

I just checked
<[https://mixpanel.com/trends/#report/ios_13>](https://mixpanel.com/trends/#report/ios_13>)
and it shows iOS at 85%.

About a month ago, I started releasing versions of our app on iOS 13 in
TestFlight (I wanted to use the new SF Symbols) only to discover there are a
lot of iPhone6 models out there. My first reaction, was "c'mon, that's a 6
year old iPhone, time to move on!" until I found that Apple kept selling the 6
all the way through 2017. A lot of "budget" buyers purchased iPhone 6's up
through that period. So I've come to be skeptical about these claims of
adoption rate. I subsequently reverted to iOS 12. :(

~~~
barbecue_sauce
I asked this question because I still use an iPhone 6, and can't update past
iOS 12. My MacBook Pro from 2013 can upgrade to Catalina and handle developing
with it, but I'd rather have a compatible device than rely on the phone
simulators.

------
kdot
Interesting how most of his points are exactly how Flutter is implemented. For
example the trailing commas, and no assumed defaults.

------
RedComet
Things with "considered harmful" in the title should be considered harmful.

~~~
sgerenser
Considered Harmful essays considered harmful:
[https://meyerweb.com/eric/comment/chech.html](https://meyerweb.com/eric/comment/chech.html)

------
halayli
I am not sure it's a good idea to take advice from someone that picks such a
background color

------
Iwork4Google
To the person who wrote this, I would suggest SwiftUI is not for you. Please
just go back to writing Objective-C or learn some good ol' UIKit. You can then
have full control over whatever color you want your buttons to show up as, and
where to have them show up, and with whatever padding you like, and as a bonus
you can use commas and all kinds of great additional syntax all over the
place. (I think what SwiftUI is for, has largely flown over your head).swiftly

