Earlier quoted context omitted.
Haskell's syntax isn't actually that complicated. There are some common functions with operator names that can be hard to read if you're not used to them, but those are library defined. The syntax itself is actually fairly simple. And incidentally, this would probably be something like (EDIT: made example more realistic): filter personIsValid (map initPerson names) in Haskell. Which looks much cleaner than the lisp t…
That's because your code assumes those convenience functions exist while the parent's code writes out the anonymous functions. The direct translation of yours' to Clojure would be: (filter valid-person? (map init-person names)) Meanwhile, the direct Haskell translation of the parent comment is: filter (\p -> isValid p) (map (\n -> Person n) names)
Swift and the Legacy of Functional Programming
61–70 of 188 posts
Re: Swift and the Legacy of Functional Programming
#62Earlier 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…
I can't help thinking like a microprocessor. Even when mixing functional style into my code, my brain tries to get a grasp on how it's going to be processed. So the first example looks to me like two loops (hopefully the compiler does a better job on that), while the second one is obviously one loop. I am already trying to guess how a compiler would parallelize that...
The first example is simply more abstract. It might be a single loop in case the implementation is lazy, it might be two loops in case it is strict. However, look closer. Those filter and map operations can be applied to basically anything you want, including asynchronous / infinite streams.
Your second loop on the other hand would have a hard time being translated to anything else than something that works on finite lists and that builds a finite buffer and not doing anything else while doing this.
Or in other words, your knowledge about this manual loop is not transferable ;-)
Re: Swift and the Legacy of Functional Programming
#63Earlier quoted context omitted.
Haskell's syntax isn't actually that complicated. There are some common functions with operator names that can be hard to read if you're not used to them, but those are library defined. The syntax itself is actually fairly simple. And incidentally, this would probably be something like (EDIT: made example more realistic): filter personIsValid (map initPerson names) in Haskell. Which looks much cleaner than the lisp t…
That's because your code assumes those convenience functions exist while the parent's code writes out the anonymous functions. The direct translation of yours' to Clojure would be: (filter valid-person? (map init-person names)) Meanwhile, the direct Haskell translation of the parent comment is: filter (\p -> isValid p) (map (\n -> Person n) names)
Re: Swift and the Legacy of Functional Programming
#64Earlier quoted context omitted.
That's because your code assumes those convenience functions exist while the parent's code writes out the anonymous functions. The direct translation of yours' to Clojure would be: (filter valid-person? (map init-person names)) Meanwhile, the direct Haskell translation of the parent comment is: filter (\p -> isValid p) (map (\n -> Person n) names)
Huh? No, anyone who writes it in Haskell would not use those lambda abstractions. You would just use "filter isValid (map Person names)".
Re: Swift and the Legacy of Functional Programming
#65Earlier quoted context omitted.
Haskell's syntax isn't actually that complicated. There are some common functions with operator names that can be hard to read if you're not used to them, but those are library defined. The syntax itself is actually fairly simple. And incidentally, this would probably be something like (EDIT: made example more realistic): filter personIsValid (map initPerson names) in Haskell. Which looks much cleaner than the lisp t…
That's because your code assumes those convenience functions exist while the parent's code writes out the anonymous functions. The direct translation of yours' to Clojure would be: (filter valid-person? (map init-person names)) Meanwhile, the direct Haskell translation of the parent comment is: filter (\p -> isValid p) (map (\n -> Person n) names)
However you're right that the function names would probably be a little longer in practice, and I've edited my example to reflect that. (But they're not convenience functions, they just have longer names due to Haskell's more limited namespacing)
Re: Swift and the Legacy of Functional Programming
#66Earlier quoted context omitted.
For me the problem with Haskel (and, by extension, Swift) is the syntax is very complicated. The example above is better taught through a functional language that has almost no syntax like a Lisp. (filter (fn[p] (p :valid?)) (map (fn[n] (Person n) names))
Haskell's syntax isn't actually that complicated. There are some common functions with operator names that can be hard to read if you're not used to them, but those are library defined. The syntax itself is actually fairly simple. And incidentally, this would probably be something like (EDIT: made example more realistic): filter personIsValid (map initPerson names) in Haskell. Which looks much cleaner than the lisp t…
I'll admit Lisp's myriad nesting of brackets is not ideal either. But surely there are more elegant and intuitive notations for functional scoping than is seen here.
Re: Swift and the Legacy of Functional Programming
#67I'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.
persons = filter isValid (map init names)
to both. Swift just isn't really a functional language in any useful sense.Re: Swift and the Legacy of Functional Programming
#68I'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.
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 accumulation takes place, and how that value is derived. It's not hard by any means, but the first one is far more straightforward.
Re: Swift and the Legacy of Functional Programming
#69Ask five programmers to define functional programming, get fifteen different answers.
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…
I offer a definition of "functional programming" as "based on semantics of lambda calculus".
Re: Swift and the Legacy of Functional Programming
#70Earlier quoted context omitted.
Haskell's syntax isn't actually that complicated. There are some common functions with operator names that can be hard to read if you're not used to them, but those are library defined. The syntax itself is actually fairly simple. And incidentally, this would probably be something like (EDIT: made example more realistic): filter personIsValid (map initPerson names) in Haskell. Which looks much cleaner than the lisp t…
Except in these two brief examples, Haskell employs syntactic sugar with hidden semantics that nobody but an acolyte would understand (periods and two kinds of brackets mean what?). At least the Lisp scoping here is explicit and employs minimal abstruse sugar. I'll admit Lisp's myriad nesting of brackets is not ideal either. But surely there are more elegant and intuitive notations for functional scoping than is seen…
Admittedly, it might be written with $ in practice, but that's a fairly simple idiom, and I tend to avoid it.