
The Curious Case of Swift's Adoption of Smalltalk Keyword Syntax - mwcampbell
https://blog.metaobject.com/2020/06/the-curious-case-of-swift-adoption-of.html
======
saagarjha
As is tradition, I'm going to take the discussion one level up and talk about
the language as a whole, although my issue is related to this syntactical
change. The problem Swift has right now is that the review process is marred
by _huge_ conflicts-of-interests. The people reviewing proposals are very
closely affiliated with, or sometimes the same people, that proposed it and
want it implemented. And that's not to say they aren't smart, reasonable
people; quite the opposite: it's just that they have their own interests when
they're adding features to the language, and they ignore the community when
doing so.

When initial SwiftUI changes came through, they were "proposed" by Apple
engineers even though they already shipped in Xcode. Sure, they got a bit of
feedback and change, but everyone largely knew they were going in regardless
and they did. When callAsFunction came in (which I actually think is a useful
feature, just spelled horribly) it was obvious that it was being pushed
heavily by the Swift for TensorFlow people. And who reviewed it? Chris
Lattner, who approved it even though _nobody_ really liked the name at all.
And with this case we see a fairly dubious benefit being pushed forward by the
team at Apple, and everyone knows it's going to be for some sort of SwiftUI
DSL thing, except they can't really tell us what it is and currently it
provides a new the way to call a bunch of functions that is unergonomic and
extremely special-purposed.

When people say that Swift is adding "useless features" they don't really
think that Swift should stop evolving; it's just that they're frustrated that
stupid things like these keep getting added and that the Swift Evolution
community as a whole is unable to stop them from being merged in or modified
substantially.

~~~
alexashka
I'd take it up a few more levels and ask about the elephant in the room: in
what significant way is this language better than C#?

This outrage over closures reminds me of tabs vs spaces - it's one level above
utter lunacy. Who gives a shit what the syntax is? Didn't we use Objective-C
not long ago? Programming languages are a tool for me, not an artistic
expression of text on a screen.

What has this language allowed me to _build_ that I couldn't in Objective-C?
Let's use empirical evidence - why do we have electron apps for something as
basic as a chat app (Slack) instead of a native app?

We're going _backwards_ in software tools as far as I can tell. Everything is
more complicated and fragmented and Swift is a part of this mess, not a
solution.

Sorry, carry on with expressing opinions about syntax and pointing out that
those who pay for the juke box, get to select the songs and are hypocrites
when they pretend otherwise and press 'Billie Jean' when most people wanted
'Thriller'.

~~~
musicale
> in what significant way is this language better than C#?

\- direct compilation to native code with static analysis and optimization

\- automatic reference counting (more predictable/consistent performance vs.
garbage collection)

\- good support for native iOS and macOS app development

\- ranges

(But on an unrelated note, I have to say it's disappointing to me to find any
language in 2020 (Java...) that doesn't support named and default parameters.)

~~~
liversage
Ranges was added to C# 8.0.

------
skohan
I don't really get this complaint:

> The already weird-ish addition of Smalltalk/Objective-C keywords inside the
> f(x) syntax: f(arg:x)

I'm a huge fan of named arguments in Swift. It's one of the things I miss most
when working with languages which don't have it.

For instance, I do a lot of work with computer graphics, and in that case you
end up with a lot of functions with a lot of arguments for things like
configuration. With named arguments, code becomes almost self-documenting.
Without them, I just end up using comments in their place, but of course then
I don't have the compiler making sure this is correct.

It's a totally optional language feature, and adds a lot of value in some
cases.

~~~
choeger
Unfortunately, named arguments lead to arbitrary-order arguments which then
make partial application quite awkward.

Think: f(fst:x, snd:y), what is the type of f(snd:4)?

I think this can be implemented, but then f(3, fst:5) is either an error or
counter-intuitive.

~~~
skohan
Swift's approach to this is pretty good. Arguments have a fixed order, and
whether or not they are named at the call-site is explicitly decided by the
author of the function signature.

In practice the order and identity of the arguments is quite clear in Swift.

~~~
codetrotter
As someone who kind of jumped into Swift coming from other languages, I still
find this kind of stuff confusing.

Is there a good intro to Swift that goes through only what is unique/peculiar
about Swift and explains that in a good way to someone that already knows how
to program?

~~~
bluk
I don't know if you tried reading The Swift Programming Language book (
[https://docs.swift.org/swift-
book/LanguageGuide/TheBasics.ht...](https://docs.swift.org/swift-
book/LanguageGuide/TheBasics.html) ). It's a fairly quick read and has brief
explanations with simple examples. You can skip some sections if you have
prior programming experience, but if you're confused about Swift's function
arguments, you may want to skim even the basics since a few things like
control flow (e.g. the switch statement) are unique compared to C/C++/Java/C#.

------
AJRF
I would really hate to be learning Swift now. I started using it around the v2
release and I think it had nice syntax & was relatively small and opinionated.

Now there are so many ways to the same thing it must be a nightmare to teach.
Each way of doing the same thing is in its own way nice, but they seem to just
be accepting every half-way decent proposal for things they've already solved.

I feel like SwiftUI had brought a number of challenges that have massively
complicated the language and you can really feel it when you bump up against
things that have been tacked on to make SwiftUI work (which it looks like they
are getting around to smoothing out now - multiple trailing closures is very a
much a problem compounded by SwiftUI).

It's a shame, I loved this language from v2 -> v4, v5 was a good release but
started to muddy the waters and now its just getting continually worse.

~~~
matt2000
I agree with you. When Swift was introduced it was billed as a modern
replacement for ObjC that was easier to learn, even a good choice as a
language for learning to program. I'm not sure it was ever that, but it sure
isn't now. I just got back into a project written in Swift 3 and had to change
a bunch of stuff to get it to work in Swift 5. Why? I keep hearing the
language is going to be stable "soon" but that doesn't appear to be happening.

Swift appears to be a language for the captive audience of iOS devs, who are
able to keep up if that's all they're doing. I don't really see it being
adopted anywhere else.

~~~
skohan
To be fair, the pace of source breaking changes has slowed down considerably.
From Swift 1 to Swift 3 there were many breaking changes between versions, and
automated migration was very necessary. Between 3 and 4 there were some
changes, and between 4 and 5 almost no source breaking changes.

I think it's actually fair for a new language to take a somewhat cavalier
approach to backward compatibility. I would rather not be stuck with all the
naive mistakes made in the first version of a language just to avoid
migration.

------
simias
>And that's the frustrating part: this stuff was and is available and well-
known. At least if you bother to look and/or ask. But instead, we just choose
these things willy-nilly and everybody has to suffer the consequences.

That could be it, or that could be that these days any language that doesn't
have a syntax vaguely resembling C on one hand or Python on the other it is
considered niche or "weird". You'll also have an endless stream of people
commenting (mostly from the Python side) that your language is noisy, because
they won't take the time to understand its syntax and it won't read like
pseudocode, and that's a bad thing for some reason. But I digress, because
that's a pet peeve of mine.

Anyway, my point is that if Swift had Smalltalk-like syntax it would not have
been nearly quite as marketable. The situation with Javascript is somewhat
similar: under the hood the language is more like a Lisp than C, yet it
awkwardly uses C-style syntax (and weird rules for automatic semicolon
insertion, because that's more like peusdocode that way, and that's a good
thing for some reason).

~~~
mpweiher
> Smalltalk-like syntax would not have been nearly quite as marketable

This was one bit I left out: with Objective-C, Apple had firmly established
keyword syntax in a Tiobe top 3 language, albeit within square brackets, so
there was absolutely no need to do this for "marketing". It truly was
snatching defeat from the jaws of victory.

> that your language is noisy

Smalltalk is about as syntactically quiet as you can get.

~~~
kiawe_fire
Was not "marketing" one of the biggest driving factors of moving to Swift,
though?

Objective-C ranked highly in usage, but largely because of it being necessary
for iOS development.

At the same time, it was common outside of the Apple bubble for devs wanting
to make something for iOS to complain about having to learn this "weird
language with square brackets" that "only Apple uses", and "why can't we just
use something like Java like we can with Android?"

With, of course, zero knowledge of Objective-C's Smalltalk roots, or its
purported ethos.

I know it's more complicated than "square brackets bad", with all the C code
mixed in, and memory release pools and all, but in general, Apple _did_ still
have a marketing problem courting outside developers to build native apps
without resorting to "web view" wrappers.

I love Swift, I really do, but I would love something that feels more directly
Smalltalk-esque even more. Swift decidedly feels like the goal was to make
something that looked familiar enough to the C / Java / Javascript / C-like
devs to get them on board, without tossing out some of the core benefits of
the Smalltalk ethos. Which, apparently, means using C-like methods with
parentheses at first... until you reach special cases where you don't.

Smalltalk is, IMO, a great example of how something can both be very
expressive yet very minimal... but that inherently means ditching some very
familiar syntax. As soon as you do that, you lose a lot of C-like developers
(be it rightfully or wrongfully so).

~~~
mpweiher
> Apple did still have a marketing problem courting outside developers

Apple categorically did not have a problem courting outside developers at this
point in time. They hit 20m registered developers in 2018:

[https://techcrunch.com/2018/06/04/app-store-
hits-20m-registe...](https://techcrunch.com/2018/06/04/app-store-
hits-20m-registered-developers-at-100b-in-revenues-500m-visitors-per-
week/?guccounter=1)

Yes, this was after the Swift announcement, but the trajectory was in place
way before that.

WWDC has been completely sold out for how many years? At first, it sold out in
a couple of weeks, then a couple of days, then a couple of hours and finally a
couple of minutes or even seconds. Then they started doing the lottery and
even that was a while ago.

> but that inherently means ditching some very familiar syntax

Swift has tons of unfamiliar syntax. And you don't have to adopt Smalltalk as-
is. Objective-Smalltalk, for example, has class definition syntax and uses
curly braces. Those are not big deals. Keyword syntax, on the other hand, _is_
a big deal, as the example of Swift shows.

Because you _do_ want argument labels, and you _do_ want to pass closures. But
that just gets messier and messier.

------
chmaynard
It seems like every Swift-related discussion here eventually devolves into a
debate about the design and evolution of the language. Okay, I'll weigh in.

Comparing Swift with other important languages I have used such as C and SML,
I think what's missing in Swift is a philosophy that inspires, motivates, and
guides its development. I think Chris Lattner described Swift as a modern,
practical language. Those are general characteristics but not the basis for a
real philosophy.

Others have described Swift as a "car crash" or "kitchen sink" language and I
think those metaphors are apt. Swift seems to be trying to be imperative,
functional, OO, and reactive all at the same time, with Obj-C compatibility
thrown in for good measure. Complexity and intractability will inevitably
follow.

~~~
skohan
I actually like the kitchen-sink nature of Swift. If I could articulate a
philosophy of Swift, it would be that the language prioritizes expressive,
ergonomics and safety (in the single threaded case) over everything else.

The fact that you have a kitchen sink of language features lets you carve out
the language of your choice and write code according to whichever paradigm
suits you as a developer.

In spite of that, it might be a matter of opinion but I generally find Swift
code among the most readable given the nature of the type system, and
decisions around named arguments and when and how type inference may be
applied.

~~~
hu3
The issue is we don't work alone. There are different people, teams and third-
party code we have to deal with. And their preferred subset of a kitchen sink
language can vary wildly.

> The fact that you have a kitchen sink of language features lets you carve
> out the language of your choice and write code according to whichever
> paradigm suits you as a developer.

~~~
skohan
Well then the responsibility would be on the team to agree on a subset of the
language and a set of design patterns to use. This is a process which happens
in every language (with the exception of Go to some extent since it's so small
and strict) but with Swift you have a bit more freedom over where you will end
up.

With regard to 3rd party code, you're also free to chose libraries where you
agree with the interface paradigm they've chosen.

I find this concern to be a bit overblown. In practice I've never really run
into a case where somebody is doing something really exotic and inscrutable in
Swift, and it's generally easier to understand than, for instance, a really
esoteric Scala code base or a Rust project making heavy use of
metaprogramming.

~~~
hu3
Let's agree to disagree because in my practice:

\- Teams: Less experienced developers will use fancy features trying to be
smart. Every subset of the language finds it way on Pull Requests I review.

\- People change teams

\- People change companies

\- Third party code: It's not realistic to filter out libraries based on their
use of the language. Who even has time to review that? Not to mention that
high quality libraries are scarce enough that if you start to filtering out
libraries you often end up with none.

And the code doesn't have to be "exotic or inscrutable" to be a negative. It
just needs to be unnecessarily of high cognitive load for it to impact use of
the language. I've seen Swift developers squint at Pull Requests trying to
gasp what certain part of the code was doing. It ended up being needless sugar
and in turn a bit of everyone's time was wasted.

That mindset of "just pick whatever part of the language suits you" is why C++
is what it is.

------
weiming
Curious question as I am not a compiler expert.

I have to do front-end iOS work from time to time and it's surprising how bad
auto-complete can be in Xcode with Swift even after all these years: still
randomly sluggish, randomly stops working inside closures including completely
losing syntax highlighting inside the closure, and even Cmd+clicking to see
the definition is a hit-or-miss as it sometimes opens up a blank editor and
just spins. I would have thought that Swift having a strict type system would
have made the IDE experience better, not worse. Don't know if the grammar is
too complex or if it is the bridging with ObjC stuff or something else that
made it difficult to build a robust solution. Can anyone shed light on this?

My points of reference are rust-analyzer, or just VSCode with Typescript, both
very snappy although of course the languages are very different. If anything
I'd expect Swift to be closer to Rust experience-wise since they both have
pretty strict grammars.

~~~
Pulcinella
Don’t think this will help you, but maybe provide some comfort in that you are
not alone. I work in Swift and XCode everyday and still run into this problem
occasionally. XCode still indeed will sometimes (seemingly randomly) lose
syntax highlighting. It seems to be, at least sometimes, related to when you
try to do something a bit too clever with closures (especially closures inside
closures) and marking lots of changes at once, especially across targets. The
biggest problem is that when the indexing required for syntax highlighting
fails, there is no insight into why it failed and no way to force Xcode to re-
index except by restarting Xcode. Building should re-index, but in practice
this indexing is not as extensive as restarting Xcode.

~~~
LordIllidan
Instead of restarting Xcode you can also flip the file target, changing it
will trigger an index.

------
jmull
Swift language evolution seems to be heading in a bad direction. This is
another change that adds nothing but extra, obfuscating complexity to the
syntax.

Now you’ll have to read and write yet another syntax variant, with slightly
scrambled separators and brackets.

------
wool_gather
I enjoy reading Marcel's Swift contrarianism (even if I don't always entirely
agree with it). I work with Swift and ObjC on a daily basis. I remember the
entirely appropriate skepticism that we in the Apple ecosystem had for ObjC
when it was the main language. And I'm getting more and more tired of that
healthy skepticism having turned into pointless bashing, accompanied by tall
frosty pitchers of Swift kool-aid.

No language is perfect, and it's important to be cognizant of the tradeoffs
and flaws. There's no denying that Swift is a powerful language in many ways.
But there's also no denying that the chosen means to that power has costs. The
most obvious is a lot of complexity, both essential and non-essential. Which
brings us back to the article and the peculiar way multiple trailing closures
ended up being integrated.

------
musicale
Like the author, I also wouldn't mind a Smalltalk syntax flavor for the whole
Swift language. ;-)

Though having used Python a lot, I've also become something of a fan of
braceless, indented syntax, which I find to be clear and conserving of
vertical space.

But I do understand the main argument for making it C-like: they wanted to
make an easier transition for Apple developers who were already using
Objective-C, and others who might be coming from Java/C#/C++/JavaScript/et
al.. Also Smalltalk's syntax, while simple, orthogonal and versatile, simply
never caught on the way C's did.

------
asplake
Arguably, the new syntax makes the anonymous trailing closure the special case
now. Having done a bit of Ruby in the past I can see why it might be
reasonable to have both.

------
logicprog
I checked Swift out really early on in its lifecycle, and, ignoring all the
bugs, what immediately turned me off was this sense of _to many features_ ,
even then. Not that a language having a lot of feature is bad - I use Rust for
heaven's sake! - but there didn't seem to be a consistent purpose or logic
behind it. I just got a really bad feeling in my gut about how the language
would develop.

So I left it alone ASAP.

Now, my fears are confirmed. Swift is now iPerl.

------
c-smile
Just in case, in Sciter script that could be written simply as:

    
    
       element.animate {
         duration: 300ms,
         completion: () => this.remove()
       }
    

Explanation, this syntax construct

    
    
       nmtoken {...}
    

is just a sugar for this:

    
    
       nmtoken ({...})
    

And that is good old function call with single object/map literal as a sole
argument.

By the way this construct can be added to JavaScript without breaking existing
code.

~~~
logicprog
Hashmap literals are the right approach to named arguments and functions-as-
control-structures IMHO. Ruby does this too IIRC. It's great because it re-
uses existing syntax and semantics instead of adding edge cases. You can even
add syntax sugar like you just demonstrated.

------
neilv
After spending a lot of time with Scheme (which is both relatively clean, and
strong at syntactic extension), but doing iOS SwiftUI work at the moment, some
of the Swift sugar is a reminder that Swift is a very different language.

But I'm not above playing with sugar, including Smalltalk-inspired ones. In
Racket, as an exercise, I implemented a straightforward way to do Smalltalk-
like syntax for procedure calls.

If the head of a list expression is a symbol that ends in a colon, then it was
assumed to be the Smalltalk-ish procedure name sugar. A syntax like this:

    
    
        (foo: bar from: (+ 1 2) to: (funky 3))
    

would be translated by the reader to this procedure application:

    
    
        (foo:from:to: bar (+ 1 2) (funky 3))
    

You'd probably define the procedure in the usual Scheme way, like this:

    
    
        (define (foo:from:to: source start end)
          ...)
    

Of course, I wouldn't use this complicating sugar in real code without a good
reason.

------
kitd
The trailing closure syntax is used in Groovy too. It is very useful for
creating builders that look almost declarative, but provide access to flow
control features in the language.

------
jtdev
The closure obsession in Swift is really off putting. The amount of
indirection in the language is frustrating and seems to be there due to an FP
zealot somewhere in the language design team at Apple.

~~~
skohan
I tend to find it really powerful and nice. The lightweight closure syntax is
something I often miss in other languages

