Live data from Hacker News

Swift and the Legacy of Functional Programming

realm.io

111–120 of 188 posts

Re: Swift and the Legacy of Functional Programming

#111
post #107

Earlier 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?

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 know that's how map and filter work, so it's trivially easy to know that those guarantees hold.

Re: Swift and the Legacy of Functional Programming

#112
post #103
post #68

Earlier quoted context omitted.

I find the first one to be far easier to read. You can basically just read it from top to bottom and know exactly what it does. "Take names, turn each one into a Person, keep the ones that are valid." The second one takes a lot more work. First, I have to read through the code and recognize that this is a loop that accumulates values into a new array. Then I have to pick it apart and see exactly where the accumulatio…

Is the first one two loops or one?

It depends. Using lazy data structures, transducers, or a number of other common tricks would turn it into one loop. Haskell, Clojure, Ruby, Scala, Swift, and many other languages make it pretty easy to do.

Re: Swift and the Legacy of Functional Programming

#113
post #103
post #68

Earlier quoted context omitted.

I find the first one to be far easier to read. You can basically just read it from top to bottom and know exactly what it does. "Take names, turn each one into a Person, keep the ones that are valid." The second one takes a lot more work. First, I have to read through the code and recognize that this is a loop that accumulates values into a new array. Then I have to pick it apart and see exactly where the accumulatio…

Is the first one two loops or one?

Two. These methods are not lazy by default. Of course, you have to know the language pretty well to know that, but I do. For anyone wondering, you can write names.lazy.map(...) to get lazy evaluation.

Re: Swift and the Legacy of Functional Programming

#114
post #107

Earlier 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?

In the first one, you are simply telling it to map and filter every element. Since you can do that to each element in an independent way and the code is more abstract, the map and filter can be done in parallel without you knowing (I'm not sure if would execute in parallel in Swift, I know that in java you can change the way it does it by using parallel streams).

But in the second example, you are telling it to iterate over each element, sequentially. Since you are telling step by step what needs to be done, it's not parallelizable unless you implement it to be so.

Re: Swift and the Legacy of Functional Programming

#115
post #104

Earlier quoted context omitted.

Most languages implement map and filter in terms of lazy sequences so they would not allocate an intermediate list (Scala is an exception but I believe you can request laziness).

hmm, i don't think lazyness is enough. for example, in the billion names example, let's say the first and last elements are valid. at the first step you'll wind up with something like validPerson : thunk after n steps where n validPerson : invalid : invalid : invalid : ... : thunk then finally at n = 1e9 validPerson : invalid : ... : validPerson because the intermediate calculations still need to happen. getting that…

Even Java manages to get your example to work efficiently with map/filter. It's not rocket science. Just because some library designers screwed it up doesn't invalidate the whole concept.

Re: Swift and the Legacy of Functional Programming

#116
post #107

Earlier 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?

As a matter of fact, any implementation of the same algorithm has the same parallelizing possibilities. You just need a smart enough compiler.

But a "smart enough compiler" is what compiler people say when they are talking about their version of the abstract anthropogenic equivalent AI. The fact is that the first one is much easier to parallelize, so that real implementations actually do it, while the second one is not done on practice. And it's easier to parallelize because there are some extra guarantees on the signature of those functions that a for loop does not give.

Re: Swift and the Legacy of Functional Programming

#117
post #78
post #59

Earlier quoted context omitted.

That's not a function, that's a closure. And you can simulate that in C by creating a struct that contains the function pointer and the set of captured data (and then when you invoke the function you pass the struct to it as a parameter).

Yes, hence the distinction between first-class features and others, which you have to implement yourself.

The parent comment said C function pointers aren't functions. They are. They just aren't closures.

Re: Swift and the Legacy of Functional Programming

#118
post #81
post #58

Earlier quoted context omitted.

Because that makes the term meaningless. You may as well ask "why don't we call any language that lets you do two actions in sequence 'procedural'?"

That doesn't make the term meaningless, it just means that "functional programming" is a victim of its own success.

If you can apply the term to every programming language in widespread use today[1], then yes, it is pretty useless. There is real value in having the term "functional programming" be meaningful and denote a certain class of languages; defining that as "any language with first-class function values" is too broad as to render the term meaningless.

[1] Even C has this with Apple's Blocks extension (http://clang.llvm.org/docs/Block-ABI-Apple.html).

Re: Swift and the Legacy of Functional Programming

#119

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.

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

#120

Earlier quoted context omitted.

Comment out all but the first and output the result. If it's what you expected, uncomment next line and output the result. Is it what you expected. Repeat... Debugging is just a specialized form of troubleshooting so the same rules apply. Bring the system to a known good, and increase until you find where it breaks.

You have a ton of these types of statements. Which one do you apply the treatment too? Your approach only allows doing this troubleshooting approach to a single place at a time easily.

How do you debug several places at the same time?

You have a ton of those statements, that's why you organize them in functions, and go debugging high level functions before you go into lower level ones, and then into atomic statements.

Anyway, you'll almost certainly want to do that in an repl. I don't know if swift supports one, if not that would be a real drawback.

Post reply on HN