
Fun with Swift - Turing_Machine
http://joearms.github.io/2016/01/04/fun-with-swift.html
======
hellofunk
> Swift is widely marketed as a functional language

If that's true, those sources reporting that are wrong. Apple itself refers to
it instead as a "protocol-oriented language" when it's not just saying
"object-oriented".

Swift is definitely not a functional language in the way that it usually
means, and Apple knows this, and any legit survey of languages wouldn't clump
it together with much more functional languages. For example, this guy[0]
knows what he is talking about.

> Where Swift shines it is in the integratiion with the underlying Objective C
> frameworks on the Mac.

>Swift is a good replacement for contexts in which Objective-C would be used.

Except when you try to do anything with OpenGL or a C-based API, like Core
Audio. Swift is really lagging for "power programming" with these low-level
APIs. It's great for beginners who use all the high-level frameworks (though
"great" is a subjective term I don't really agree with for Swift), but a lot
of people who really need to get stuff done on Apple's platform are not going
whole-hog Swift.

>If you’re coming form Erlang/Haskell world you’ll think Swift is verbose and
a bit of a mess but if you’re coming from Objective-C you’ll think “Swift is
concise and elegant”

I got to be honest, I still find I prefer Objective-C, because, it's
essentially C. I can use my C structs and interfaces with zero problem. But in
Swift, all C primitives are translated into Swift-only stuff, even integers!

And don't get me started with trying to use a C++ library with Swift,
something that's smooth with Objective-C. Which is ironic since Swift itself
is written in C++.

[0] [http://robnapier.net/swift-is-not-functional](http://robnapier.net/swift-
is-not-functional)

~~~
melling
In your provided reference, the first sentence Rob writes:

"Ever since Swift came out, I keep seeing weird comments that Swift is a
functional programming language"

Swift is often promoted as being "functional":

[http://www.raywenderlich.com/114456/introduction-
functional-...](http://www.raywenderlich.com/114456/introduction-functional-
programming-swift)

In fact, I've tagged many articles as functional in my Swift resources:

[http://www.h4labs.com/dev/ios/swift.html?q=functional&age=10...](http://www.h4labs.com/dev/ios/swift.html?q=functional&age=10000)

Want to buy a book on functional programming in Swift?

[https://www.objc.io/books/functional-
swift/](https://www.objc.io/books/functional-swift/)

~~~
s73v3r
People say a lot of things. Doesn't make them right.

------
drivebywire
For people who don't recognize the name, the author is one of the inventors of
the Erlang programming language. Erlang is famous for its approach to
mutability, concurrency, and error handling.

------
MCRed
FWIW - This is Joe Armstrong, one of the creators of Erlang. Definitely an
old-school REPL/functional guy, and I love seeing him playing around with
swift.

Regarding GUIs and IDEs: I think interface builder is the best ever way to
build UIs, far more fun and comprehensible than web development. I totally
understand why Joe wants to control every line of code and do nothing in
Xcode-- when things go wrong in the IDE they can be a pain to deal with.

For me, I think there's several common stages of Mac/iOS developer: 1\.
Newbie- needs Interface builder because GUIs are all so confusing and he
doesn't yet know the API. 2\. Control Freak -- knows enough (and spent enough
time struggling with Interface Builder, because IB isn't a magic box and you
do have to know how things are working under the hood, and the Newbie often
struggles because of this).. and so he wants to avoid IB and do everything in
code so he has absolute control. 3\. Starting to see the light-- tired of
tiresome pointless repetitive GUI code, back to Interface builder, but this
time understanding the underlying parts of it, and having a lot more fun with
IB 4\. Enlightened-- uses Interface builder for most stuff, but knows when and
where to drop down to GUI code and generally only does that in a highly
leveraged way.

One of the things I find frustrating about web development is there is no
interface builder (though some people have attempted to create them in the
past, they always seem to abandon them, unfortunately.) So you're always stuck
wit the frustration of constantly defining everything by hand-- when the
reality is there's nothing that should stop web browsers from being able to
handle auto-layout the way that iOS does.

Anyway, if you've rejected IB and are finding GUI code a PITA, try using IB in
balance.

~~~
lr
"One of the things I find frustrating about web development is there is no
interface builder"

There was, and Apple killed it. It was WebObjects Builder and it was a GUI for
interacting with the components you wrote in code in XCode when doing
WebObjects development. It was the web version of IB, and, in its day, it was
awesome.

------
coldtea
> _Which to my mind is horrendous. The closure f does not capture the value of
> i at the time when f is defined, changing i after f was defined make
> nonsense of the idea of a closure._

Of course it should change i after the closure was defined, since the closure
doesn't copy but refer to that i.

Looks like a fully proper closure.

Which language does this differently?

~~~
mikeash
Objective-C does it differently by default:

    
    
        int x = 0;
        void (^block)(void) = ^{ NSLog(@"%d", x); };
        x++;
        block();
    

This will log 0, not 1. If you want to capture by reference rather than by
value, you add __block to the declaration of x.

For a lot of people coming to Swift from Objective-C, this is a surprising
change, especially if Objective-C was their first language with closures.

~~~
qwertyuiop924
That's a block, not a closure. It's still an anonymous function, but the
semantics are slightly odd, and derived from Smalltalk, probably altered some.

~~~
mikeash
"Blocks" is what Objective-C calls closures.

A closure is just a function that captures ("closes over") the surrounding
scope.

Edit: strictly speaking, the construct here is an anonymous function.
Objective-C calls them "blocks" and Swift calls them "unnamed closures" or
"closure expressions." Both are, or at least can be, closures. (I'm not sure
if the term "closure" can be used to refer to a function that _could_ refer to
variables in the enclosing scope but doesn't. Probably not.)

~~~
qwertyuiop924
What you seem to be calling a closure refers to a lambda in a lexically scoped
language. Particularly when they refer to free variables.

Blocks are in fact lambdas, or at least closures. I was wrong in the above. In
some early versions of smalltalk, blocks had some odd semantics that made them
different, but this is no longer true. However, judging by the Objective-C
example above, Objective-C blocks don't create true closures, as a true
closure would have the semantics of the Swift code from the article.

------
musha68k
I'm currently working on a project which makes me jump between Swift and
Erlang/Elixir on a regular basis. I actually enjoy Swift's OCD typing,
particularly in exchange over not having to maintain those mind-numbingly
redundant header files any more.

All in all I feel as if Steve Jobs would have been proud of what the Swift
team has accomplished - lots of "great artists steal" in the functional
programming department while still being disciplined enough to not go
overboard with features and staying true to Apple's design culture in general.

That said the lack of pattern matching really is something I've come to miss
too and Elixir application code in general feels much more elegant and almost
effortless to read and write in comparison to Swift.

Playgrounds are fun and all but IMHO Joe is very much right - all the cruft,
the arcane NeXT "magic spells" as well as the mouse-heavy Xcode dependence
should make way for new ways to do things. The kids "ain't stupid" I mean
young programmers probably all grow up with some command-line fu, essentially
making Unix the new lingua-franca (besides Javascript;) so why not embrace
OSX/Darwin and go for something more along the lines of how RubyMotion does
things?

Whipping up a simple GUI with a couple of action functions really should come
with the least amount of needlessly distracting development abstractions.

It probably would also mean less Apple developer time wasted on the next
potentially buggy Xcode feature..

Less is more, but again Apple is getting there, especially now that we might
be on a path to more complementary open-source development tooling - so to me,
doing Swift with Xcode is super productive and fun already!

------
e28eta
I think the author should do some more reading about Swift. He complains about
a lack of inferred typing and pattern matching, two things which Swift _does_
support. It's more limited than Haskell, but it's there.

I also disagree with his statement that Objective-C is better for writing an
operating system.

He seems to conflate using Xcode with the built-in support it has for xibs to
do UI layout. You don't have to forego all of the features of the IDE just
because you prefer to do UI layout in code.

~~~
allsystemsgo
> You don't have to forego all of the features of the IDE just because you
> prefer to do UI layout in code.

I don't understand why you would do your UI layout in code if you can avoid
it. If someone ever joins my team or inherits my code base, they're now partly
responsible for maintaining the UI. Xib's and storyboards help with
maintainability, legibility, and drastically lower the number of lines of
code. The author even says:

> Find an example program that works then reduce lines until I can reduce no
> more making a minimal example that works - then understand every line

If you care about the line count, then why are you doing all your UI in code?

~~~
cballard
Layout done in code:

\- Is type-safe, which is verified at compile-time.

\- Will break at compile-time if a breaking change is made.

\- Can be null-safe, without having to use Optional for everything.

\- Can do things iteratively.

\- Can use constants, so that you can easily modify standard paddings and
sizes globally with one change.

So those are some of the advantages of doing layout in code.

~~~
allsystemsgo
Right but you'd have to document what each constant represents. Interface
builder gives us a universal language. You know what the UI will look like or
how it will resize etc. because it's right there. There's no confusing
constant names with magic numbers. You know the _why_ behind the constraint
values because you can see it.

~~~
rimantas
Constants are not magic numbers. And with proper naming they document
themselves. For more cusotm UI's you won't know how UI will look like. It got
better with @IBDesignable but still not enough.

------
thejay
For some reason reading the post gives me a deja vu of a win32 GUI programming
tutorial :)

~~~
dguaraglia
Hehe, must be all the HWNDs in the code :P

------
iraphael
> The closure f does not capture the value of i at the time when f is defined,
> changing i after f was defined make nonsense of the idea of a closure.

I have an incomplete understanding of functional programming. Are there other
uses for closures (besides readability and practicality) that still work if
they don't capture the value of i? If not, is this something someone should
suggest as a change in swift-evolution?

~~~
tel
He's complaining about mutable state, essentially. The function `f` captures
reference to `i` but does so transparently. One might expect that `f` would be
free of side effects, but since `i` can be re-bound whenever this is not the
case.

Essentially it comes down to the semantics of `=` whether it's declaration or
assignment. Swift appears to choose it to be assignment. If I remember right
you can declare things constant which would effect declaration only (sort of)
but clearly there's an expectation that this happens all the time.

~~~
masklinn
> He's complaining about mutable state

Bindings rather than state, the author has no issue with captured objects
being mutable, only with the captured environment being mutable.

------
ldesegur
Swift feels very immature in many areas. For example, Swift fails with
generics out of most ordinary cases. Today, you still can't restrict protocol
conformance (inheritance clause) to a type-constrained extension. That's a big
issue with arrays. A struct wrapper is the go-to solution for many things
where Swift generics break down and it's not the best or more elegant way to
resolve its limitations. Many hopes for Swift 3.0 but I doubt they'll fix
those.

------
BuckRogers
I agree, once you step outside the bounds of "text only" you bring on a whole
mess of complexity. I've always disliked programming in Eclipse or VS, it just
feels wrong compared to a nice simple .py file or whatever you're working with
that can be used with any editor you want.

It seems like language complexity brought on IDEs, rather than anything else.
They tried to fix the verbosity of C++ and in turn, Java, by creating new IDEs
rather than a newer higher level language.

------
ben-schaaf
The lack of proper syntax highlighting and long lines is making this really
difficult to follow on mobile.

~~~
jld89
It is actually generalized. Not only on mobile. Hard to read indeed but very
interesting nonetheless.

------
mpweiher
> Above all it had a REPL and I could program outside Xcode (which I hate).

If that's the "above all", not sure what his beef is with Objective-C. You
could always program outside of Xcode and various sorts of REPLs were/are
available.

------
lyinsteve
The author completely missed the point of named parameters. How am I supposed
to know that the string argument of "make_window" is the title?

~~~
masklinn
> The author completely missed the point of named parameters.

The author didn't miss the point of named parameters. At no point does the
author even cover the point of named parameters. The author complains that:

1\. they're inconsistent, all parameters _but the first_ are named by default
_and_ named parameters are still positional (you can't reorder "named"
parameters in the callsite)

2\. making parameters purely positional is non-obvious and ugly

And he missed the part which takes the cake: Swift doesn't actually have
_named_ parameter, parameters 1+ are _labelled_ (#1), and labels and names are
independent, you can define this:

    
    
        func foo(a b: Int, c d: Int) { … }
    

which is called with a:c:, but the bindings are on b and d. You can also
define this:

    
    
        func foo(a b: Int, _ d: Int) { … }
    

which is called as `foo(a:5, 7)` which while somewhat consistent is really
garbage.

~~~
mikeash
In Swift terminology, a and c are "external names" while b and d are "local
names." I don't see much of a difference between a "name" and a "label" here
in any case.

I don't understand why the ability to set different external and local names
is so bad. External names are part of the API, local names are part of the
implementation. It often makes sense to make them the same, but there are case
where you want them to be different, and what's wrong with that? It's
ultimately no different from loading a parameter into a local variable of a
different name and then operating on that local variable. Yes, you can use
this facility to make ugly APIs, but you don't _have_ to.

~~~
masklinn
> I don't understand why the ability to set different external and local names
> is so bad. External names are part of the API, local names are part of the
> implementation. It often makes sense to make them the same, but there are
> case where you want them to be different, and what's wrong with that? It's
> ultimately no different from loading a parameter into a local variable of a
> different name and then operating on that local variable.

Then why have it in the first place? That seems like a very odd feature to put
front and center into the language (considering a very similar effect can be
achieved with a few assignments as the function's prelude) and require using
when just wanting positional-only parameters, or consistently labelled
parameters.

~~~
mikeash
Can you explain what "and require using when just wanting positional-only
parameters, or consistently labelled parameters" means? I don't understand
that.

As for why you have it in the first place, it's just because one is API and
one is implementation, and there are sometimes good reasons to have them be
different.

~~~
masklinn
> Can you explain what "and require using when just wanting positional-only
> parameters, or consistently labelled parameters" means? I don't understand
> that.

As far as I can see (and the article notes), by default the first parameter of
a Swift function is unlabelled, and the others are labelled. That is at
callsite the first parameter _can not_ be labelled and the others _must be_.
Having either all-positional or all-labelled (but still positional) requires
specifying external names.

> As for why you have it in the first place, it's just because one is API and
> one is implementation

But again and as you yourself noted that could trivially be done with local
bindings inside the function in cases where it's desirable.

~~~
mikeash
Yes, that's true, but note that you only need to specify the external names on
the parameters that depart from the default. A function with external names on
every parameter looks like:

    
    
        func whatever(a a: Int, b: Int, c: Int)
    

A function with no external names on any parameter looks like:

    
    
        func whatever(a: Int, _ b: Int, _ c: Int)
    

I'm not sure if you understood that or thought they all had to be specified if
any were, but in any case that's how it looks.

As for "that could trivially be done," that applies to a lot of language
features in a lot of languages. Virtually all language features are redundant
in that fashion, yet they can still be useful by adding brevity and clarity.

~~~
wtetzner
The question is why is the first argument special? Also, it's weird that you
have to explicitly mark the label as "_" to get positional parameters.

I find Scala's handling of named arguments much saner.

~~~
mikeash
I think it's because the first argument tends to be named by the function
itself. For example:

    
    
        button.setTitle("Ham and Cheese", color: red)
    

Note that named parameters are still positional, they just have names too.
Using _ doesn't get you positional parameters, you already had that, it just
removes the name. (Exception: named parameters with default values can be
reordered with other adjacent named parameters with default values. Why? I
don't know.)

It is mildly annoying that you have to add an extra symbol to remove the name
for parameters after the first one, but that's the language pushing its
preferred style.

How does Scala handle all this?

~~~
masklinn
> Exception: named parameters with default values can be reordered with other
> adjacent named parameters with default values. Why? I don't know.

That's actually nice to know.

> How does Scala handle all this?

No idea about Scala. In Python 3, there are 4 "classes" of parameters:

* "positional-and-named", the basic parameter can be passed either by name or by position, though passing parameter 1 by name parameter 2 by position won't work: when actually calling the function, the interpreter first fills positional parameters left-to-right then applies named parameters, so it'll raise an error noting that one parameter got two values[0]. Can be either required or with a default value. Parameters passed by names can be passed in any order
    
    
        def foo(a, b, c=5): pass
        foo(1, c=42, b=3)
    

* positional varargs ("args"), can only be passed positionally, can follow any number of positional parameters, will be collected as an array
    
    
        def foo(*args): pass
        foo(1, 2, 3, 4)
    

* named-only ("keyword parameters"), follows either positional varargs or a special placeholder. These were not possible in Python 2 in pure Python, they're similar to 1 but can only be passed by name, they can be either required or with a default value. Like 1 but more so, named-only parameters can be passed in any relative order
    
    
        def foo(*, a, b, c=5): pass
        foo(b=6, a=2)
    

* keyword varargs ("kwargs"), may follow named-only parameters and will collect any parameter passed by name which didn't match any formal parameter, will be collected as a key:value map
    
    
        def foo(**kwargs): pass
        foo(bar=5, baz=42, qux=1)
    

The C API also allows creating true positional parameters (completely
unnamed), as far as I know that's not possible in pure Python.

[0] the reverse won't work either, at callsite Python doesn't allow named
parameters to be provided before positional ones

