
Swift and the Legacy of Functional Programming - ckurose
https://realm.io/news/tryswift-rob-napier-swift-legacy-functional-programming/
======
seanalltogether
I'm curious, does every else find this

    
    
        let persons = names
            .map(Person.init)
            .filter { $0.isValid }
    

easier to read than this?

    
    
        var persons: [Person] = []
        for name in names {
            let person = Person(name: name)
            if person.isValid {
                persons.append(person)
            }
        }
    

I understand and appreciate the value of compact code, but I find the first
one harder to read. A lot of inferred/token based coding is harder for me to
mentally parse.

~~~
svachalek
I think if the second one is easier, you've more or less been taught to think
like a microprocessor. That happens to most of us after a few years of writing
imperative code. The more abstract functional approach is, however,
conceptually simpler and more powerful at the same time. (For example, the
first one is completely open to being performed in parallel.)

With a little experience, functional programming is quite straightforward.
Practically everything comes down to map, filter, and fold, or whatever
they're called in a given language.

~~~
jkaptur
> For example, the first one is completely open to being performed in parallel

So what do you actually have to do to make this actually run in parallel? Or
do you truly get it automatically?

~~~
svachalek
I don't think that will happen in Swift, but conceptually there's nothing that
stops the compiler from doing it since you're not specifying the order that
anything happens. Some Haskell compilers can automate parallelization of the
equivalent code. But pragmatically speaking, you can convert code in this
style to parallel code without changing the algorithm; for example various
"map-reduce" servers are built around the idea of mapping and reducing, which
are fundamental concepts of functional programming.

In contrast, in the imperative form, you are specifying how items are appended
to a list, which means that any attempt to do it in parallel could change the
order of the operations and therefore the order of the result. Sure, a
sufficiently smart compiler could in theory figure out what "should" happen
and see how to optimize it, but in practice today's smartest compilers can
barely handle the functional case.

------
jonathanstrange
Yo, would be nice to have some functional programming language with decent
syntax to program apple machines. Let's call it Dylan to honor the most recent
winner of the Nobel prize for literature.

Just kidding. The bottomline of this page and talk is that _Swift is still not
functional._ But you can do cool things with it.

~~~
ubertaco
I dunno; I think the bottom line of this page is that functional programming
is a set of approaches for solving problems, and some of those approaches can
be done in Swift.

~~~
macintux
Haven't read the article yet, but the problem I find with this attitude
generally is that the constraints found in FP are what I find valuable, and
what are usually missing from languages which support functional approaches.

~~~
seagreen
Well said. I can write exceedingly low defect code without folds. I can't do
so with implicit IO everywhere, ad hoc polymorphism, and dynamic typing.

------
grabcocque
Ask five programmers to define functional programming, get fifteen different
answers.

~~~
lmkg
The term "functional programming" is overloaded, but I think there's a
sensible way to split the term into two halves.

"Purely functional programming" is writing programs to resemble mathematical
functions, with referential transparency and absence of side-effects and so
forth. Also know as "what Haskell does."

"Function-oriented programming" is writing programs using functions as your
main tool for abstraction, encapsulation, defining interfaces, unit of code
division, etc. This part of functional programming is more typified by the
Lisp family.

Most languages that are considered functional generally encourage both of
these aspects, partly because they work well together. The confusion over
definition comes from these two halves getting tangled, and some languages or
programmers emphasizing one half over the other.

Non-functional languages that are becoming "more functional" are generally
importing features from the "function-oriented" side of things, and adopting
the "purely functional" aspect as a best practice convention, if at all. It's
probably more accurate to say that they _enable_ a functional style of
programming, rather than that the _are_ functional.

~~~
js8
Actually, both of those families come from lambda calculus, except in
different way. Lisp comes from untyped lambda calculus (and adds things like
car, cdr and eq on top of it), while Haskell (and ML) comes primarily from
typed lambda calculus.

I offer a definition of "functional programming" as "based on semantics of
lambda calculus".

~~~
kazinator
Lisp does not come from lambda calculus. Anonymous functions in Lisp get their
LAMBDA name from lambda calculus, that's all. MacCarthy admitted that he
didn't even understand lambda calculus properly, which is why early Lisp was
dynamically scoped: lambdas didn't capture lexical variables. Whereas lambda
calculus is lexical. Lexical scoping was adopted in later Lisp dialects and
into Common Lisp, making those dialects retroactively related to lambda
calculus. (Emacs Lisp shows the traditional behavior of dynamic scoping;
therefore it couldn't be said to be related to lambda calculus.)

Lambda calculus is a formalization of number theory which builds up numbers
from functions. An important result is that lambda calculus is Turing
complete. It shows that we can boostrap numbers and number theory from almost
out of nothing, using Church numerals.

Lisp has never built numbers out of Church numerals; it had ordinary integers.

Also, lambda calculus, typed or not, does not have its own syntax as a data
type. It doesn't have symbols. You don't quote a symbol and pass it to a
function and so on.

So that's basically it; there is a link between Lisp and lambda calculus due
to the use of the _word_ lambda in a related way, and a somewhat stronger link
between lexically scoped Lisps (which came later) and lambda calculus.

~~~
js8
I guess you're right, it doesn't come so much from lambda calculus as I
claimed, it was more inspired by it. Although to be fair, in the time the Lisp
appeared, it was the closest thing (by a wide margin) to lambda calculus. I
think it was a valiant effort to bridge the gap in that direction (and the
design choices were influenced by the trade off that he also wanted a
practical programming language).

Also, even languages like Haskell are not based only on theoretical lambda
calculus, but they also have primitives for data types, which could be, in
theory, represented by lambda expressions.

------
melling
The talk discusses how you can incorporate a few functional techniques (map,
filter) but the speaker's main goal seems that he wants Swift to be changed to
allow for a couple of other functional ideas to be brought into the language.

Where's the Swift proposal for the enhancements? Product and Sum support?
Algebraic data types?

------
delegate
I enjoyed the talk, thank you.

The part about "lifting" a type was an 'aha' moment for me and now I
understand!*.

I mean, I did this intuitively, but now I know the name of the technique,
which is really good.

Thank you, I've learned something new today!

------
zmmmmm
There seem to be a lot of "pretend" functional languages around these days. I
have recently been engaging with Scala. Having heard and read so much about
how it embraces functional style I was kind of shocked to find the number of
limitations and practical impediments to actually using it that way. I am
starting to wonder if functional programming has finally fallen victim to the
same problem that has afflicted all other methodologies - becoming too
popular, part of the hype cycle and getting misinterpreted and misapplied
everywhere as a consequence.

~~~
lmm
Scala is about as functional as it gets - the only remotely mainstream
language that's more so is Haskell, IME. What kind of issues did you have?

~~~
stingraycharles
This sounds pretty misinformed. There are plenty of choices in between Scala
and Haskell; Clojure and Elixir are two other relatively popular languages
that come to mind.

~~~
bad_user
You might have fallen victim to misinformation yourself.

In general, functional programming in Scala tends to be more FP, with code
tending to be more pure than in Clojure and I have no experience with Elixir,
but I have some experience with Erlang and FP code in Scala tends to be held
at a higher standard than in Erlang.

Of course, you've picked 2 dynamic languages as examples and FP in dynamic
languages is different than that practiced in static languages like Haskell or
Scala. LISP developers for example don't think so much about monads or other
abstractions with mathematical foundations, because LISP developers tend to
work around such needs by doing macros (which then have composability
problems) or by bending the rules a little, or in other words I've seen no
LISP to make a serious attempt at reasoning about I/O in a pure way.

And IMO code in static languages tends to be more pure because of the types,
because by having an expressive type system, the developers then want that
type system to explain everything. Or in other words, dynamic languages are
cool for your day job, but if you want to actually feel what FP is all about,
you're better off going for a static languages like Haskell, or even Scala or
OCaml.

PS: [http://typelevel.org/](http://typelevel.org/)

~~~
stingraycharles
Thanks for your reply, I think this is a matter of interpretation of what
functional actually means. I personally consider the fact that Scala allows
you to get away with immutability so easily (as evidenced with the
implementation of all the immutable collections) a very bad thing. It might be
just a matter of taste, though; Scala was my gateway drug to functional
programming, and I considered implicit parameters and all these immutable
containers something very un-functional.

You cannot get away with these things as easily in the Erlang VM (and thus
Elixir). I agree with your assessment that Clojure with its macros is an ugly
hack, and requires discipline to get right.

Having said that, Haskell also takes a lot of discipline to get right (no lazy
I/O, for example), and allows you to get away with ugly things as well
(unsafePerformIO). The type system makes it a lot easier to get right though
(or in other words, more difficult to do the wrong thing).

