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.
Swift and the Legacy of Functional Programming
131–140 of 188 posts
Re: Swift and the Legacy of Functional Programming
#132Earlier quoted context omitted.
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…
> 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?
Re: Swift and the Legacy of Functional Programming
#133Earlier quoted context omitted.
Though by this definition, Lisp, the granddaddy of functional programming languages, is not a functional programming language.
It indeed isn't. Here's my litmus test. Is 2^100 always equal to 2^100? Let's ask SBCL: * (eq (expt 2 100) (expt 2 100)) NIL Damn object identities, ruining muh equalities. (Disclaimer: I'm not saying functional programming is the right approach for writing every program, but if a language can't even get arithmetic and relational operators right...)
An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes no guarantee that eq is true even when both its arguments are "the same thing" if that thing is a character or number.
http://www.lispworks.com/documentation/lw51/CLHS/Body/f_eq.h...
Re: Swift and the Legacy of Functional Programming
#134Earlier quoted context omitted.
The second one might be obviously a single loop, but it is not obvious that it is O(n) and depends on the implementation of "append". It also tells you nothing about how the memory gets accessed and I'm assuming here that the for loop works just as well over linked lists and over arrays. In other words your knowledge that this is a single loop can be very misleading when thinking of expected performance. Which is fin…
Excuse my ignorance but why is the first one parallelizable but not the second?
We could talk about why the first example could be parallelized of course, but that's not what I wanted to talk about and you missed the point ;-)
Re: Swift and the Legacy of Functional Programming
#135Earlier quoted context omitted.
That's just one aspect of functional programming. By that definition, almost any modern language is functional.
Take it from the other side: why would a language that allows to create higher-order functions/closures not be called functional?
As for closures, well, closures are an implementation technique. Not distinguishing between language features and implementation techniques is a part of an established tradition that comes from Lisp, but that doesn't make it any less wrong.
Re: Swift and the Legacy of Functional Programming
#136Earlier quoted context omitted.
Excuse my ignorance but why is the first one parallelizable but not the second?
They're both parallelizable, but the second one is harder to automatically parallelize. There are guarantees about the way a map function works. It doesn't mutate its input, it only has access to one element at a time, you can't access the data structure you're building, etc. All of these traits are true of the imperative version as well, but it's a lot harder to write a program which understands that. Meanwhile, you…
Can't be done.
Re: Swift and the Legacy of Functional Programming
#137Earlier quoted context omitted.
In this case, it's unfortunate that there's no, "will this name create a valid person object?" predicate. much much better to filter the names, then make the objects. In this case, as long as append is O(1), i think the imperative version has a big benefit, it avoids building the name size list of persons. If you've got a billion names and 2 valid person objects, the imperative version is a big win. Of course that pr…
> In this case, it's unfortunate that there's no, "will this name create a valid person object?" predicate. much much better to filter the names, then make the objects. No "object" is made if the name can't create a "valid person object", it'll return a stack-allocated null/nothing value. That pattern is also much better for concurrency issues. > much much better to filter the names, then make the objects. You're jus…
I think the right way to do it is with a fold.
Re: Swift and the Legacy of Functional Programming
#138Earlier quoted context omitted.
Though by this definition, Lisp, the granddaddy of functional programming languages, is not a functional programming language.
It indeed isn't. Here's my litmus test. Is 2^100 always equal to 2^100? Let's ask SBCL: * (eq (expt 2 100) (expt 2 100)) NIL Damn object identities, ruining muh equalities. (Disclaimer: I'm not saying functional programming is the right approach for writing every program, but if a language can't even get arithmetic and relational operators right...)
Functional doesn't mean "the semantics of everything is tied to its printed syntax" so that if two things look the same in the syntax, they denote the same thing. (Right?)
Suppose we take Haskell and give it an equal operator which can tell that two bignums are different instances and not equal. Does it cease being functional? What if we don't use that operator anywhere in a program and don't even know it exists; how do we know the language is not functional?
Re: Swift and the Legacy of Functional Programming
#139Earlier quoted context omitted.
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, enca…
Your " function-oriented programming " has an older and more suitable term: https://en.wikipedia.org/wiki/Procedural_programming You see, if a function isn't pure , then it isn't a (mathematical) function. But we tend to overload terms because of their marketability. In the same way that some companies wanted to overload " open source ". The general rule of thumb is that if something is desirable by the market, then…
Re: Swift and the Legacy of Functional Programming
#140Earlier quoted context omitted.
It indeed isn't. Here's my litmus test. Is 2^100 always equal to 2^100? Let's ask SBCL: * (eq (expt 2 100) (expt 2 100)) NIL Damn object identities, ruining muh equalities. (Disclaimer: I'm not saying functional programming is the right approach for writing every program, but if a language can't even get arithmetic and relational operators right...)
Structural equivalence is given by EQUALP and has of course its own limitations (but works with trees, user-defined structs and hash-tables, for example). Of course, if you use the identity comparison, you get different results. I agree CL does not fit your definition of functional programming. An implementation is permitted to make "copies" of characters and numbers at any time. The effect is that Common Lisp makes…
On the other hand, in Haskell and ML, due to their superior value-oriented design, there's no way to distinguish between “this 123456789” and “that 123456789”, or between “this list [1,2,3]” and “that list [1,2,3]”. There is only one number 123456789 and one one list [1,2,3] in the language's semantics, no matter how many copies of their representation might exist in memory.