Live data from Hacker News

Swift and the Legacy of Functional Programming

realm.io

161–170 of 188 posts

Re: Swift and the Legacy of Functional Programming

#161

Earlier quoted context omitted.

persons = [person for person in (Person(name) for name in names) if person.isValid()] This is Python.

i've been struggling with python in comprehensions since time immemorial. map/filter are a breeze.

It's easy. The first bit:

    [person
tells you that you're getting a list of persons. That's the most important part. The rest is telling you how they're getting in that list.

It's almost like a select query in (pseudo) SQL.

    select person from people where person.isvalid = true
vs

    [person for person in people if person.isvalid]

Re: Swift and the Legacy of Functional Programming

#162
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?

Naïvely, two. The compiler can probably figure out that the semantics are the same and choose depending on what its model says will be faster.

Re: Swift and the Legacy of Functional Programming

#163

Earlier quoted context omitted.

In Python, the only good language, this could be expressed as: [person for person in (Person(name) for name in names) if person.isValid()] or: filter(lambda p: p.isValid, map(Person, names)) or: persons = [] for name in names: person = Person(name) if person.isValid(): persons.append(person)

So much for "There's Only One Way To Do It". :)

That is long gone, specially regarding string formatting.

Re: Swift and the Legacy of Functional Programming

#164

Earlier quoted context omitted.

In Python, the only good language, this could be expressed as: [person for person in (Person(name) for name in names) if person.isValid()] or: filter(lambda p: p.isValid, map(Person, names)) or: persons = [] for name in names: person = Person(name) if person.isValid(): persons.append(person)

So much for "There's Only One Way To Do It". :)

In fairness, the list comprehension would probably be the most "Pythonic" way to do this. The nested iterator might be discouraged (under "explicit is better than implicit," perhaps), so a more Pythonic snippet might look like:

    persons = [Person(name) for name in names]
    valid_persons = [person for person in persons if person.isValid()]
Take this all with a grain of salt, though -- I haven't spent that much time internalizing classical Pythonicness.

Re: Swift and the Legacy of Functional Programming

#165
post #137

Earlier 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. 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…

> You're just duplicating the validation logic (or worse, the "objects creation" assumes it's given valid names and does no checks) I think the right way to do it is with a fold.

In Haskell you'd use `mapMaybe :: (a -> Maybe b) -> [a] -> [b]`[0], it's a combined map+filter+map specialised for Maybe (option types). Rust has Iterator::filter_map[1] which does more or less the same thing.

[0] http://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Ma...

[1] https://doc.rust-lang.org/std/iter/trait.Iterator.html#metho...

Re: Swift and the Legacy of Functional Programming

#166

Earlier 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...)

I don't see how support for multiple equalities makes something not a functional language. 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?

;-)

If a tree falls in a forest and no one is around to hear it, does it make a sound?

If a program satisfies a property but the compiler cannot prove it, can we still rely on it?

Re: Swift and the Legacy of Functional Programming

#167

Earlier quoted context omitted.

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.

They do, it's really slick how well they have it integrated.

Re: Swift and the Legacy of Functional Programming

#168
post #166

Earlier quoted context omitted.

I don't see how support for multiple equalities makes something not a functional language. 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? ;-) If a tree falls in a forest and no one is around to hear it, does it make a sound? If a program satisfies a property but the compiler cannot prove it, can we still rely on it?

> If a program satisfies a property but the compiler cannot prove it, can we still rely on it?

It's very simple: You can rely on what you can prove. This applies both to compiler authors and compiler users. That sometimes one can prove things the other can't shouldn't come off as a surprise. Neither party has all the information: The compiler author doesn't know the intended meaning of the program submitted to the compiler by the user. The user doesn't (need to) know the internal details of how the compiler works.

Re: Swift and the Legacy of Functional Programming

#169

Earlier quoted context omitted.

let persons = [ p | n is even better, if your programming language has comprehensions.

Eh, maybe for more complicated examples, but I think that comprehension is a lot more complicated than: filter isValid (map peopleNamed names)

Except that doesn't support multiple people with the same name.

Re: Swift and the Legacy of Functional Programming

#170

Earlier quoted context omitted.

Eh, maybe for more complicated examples, but I think that comprehension is a lot more complicated than: filter isValid (map peopleNamed names)

Except that doesn't support multiple people with the same name.

Well I was basing mine on the original. If peopleNamed in fact returns a list, then I'm not really sure what it's doing to create that? (I assumed your example was Haskell, in which case I don't think it can do anything particularly useful)

In any case, all you'd need to add is something like concat.

Post reply on HN