9 ms·
Functional Programming for the Object-Oriented Programmer by Brian Marick
- Tashtego 14y agoLooks like a good overview of Clojure and functional programming. Anyone have a review?
- whichdan 14y agoI would be interested in a review as well. Coming from an OO background, I've been looking for books/articles that focus more on "here's how you'd do that using functional programming" instead of just exercises going over syntax.
- andrewcooke 14y agoi always thought that sicp (the book here http://mitpress.mit.edu/sicp/ http://mitpress.mit.edu/sicp/) was a pretty good intro to fp for oo people. in particular, chapter 3 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html#%_chap_3 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html... shows the similarity between closures and objects, which (apart from just generally become familiar with the ideas in fp) is the main "aha" in bridging between the two. having said that, in my experience (perhaps i am just dumb, or old) fp takes a while to get used to. i first looked at haskell some 16 years ago (i can still remember reading the intro while staying in a b+b in edinburgh), before using sml and ocaml, but the first time it really felt natural to me was with clojure this year. i don't think that's much to do with clojure - it just took multiple attempts before things really stuck. perhaps the biggest help was python's slow drift (despite gvr) towards fp idioms.
- verroq 14y agoIf anything, functional programming gives you too many ways to achieve the same thing. How many ways can a reasonable programmer write the factorial function imperatively (without using the closed form formula or any dynamic programming). A maximum of two. A for loop or use recursion. But just look at how many ways you could write factorial in a functional programming language. http://www.willamette.edu/~fruehr/haskell/evolution.html http://www.willamette.edu/~fruehr/haskell/evolution.html It is truly unfortunate when your ability to program functionally is directly proportional to how much of the standard library you have memorised. This makes functional programming much harder to learn. edit: I don't really care if you downvote. I come here discuss programming.
- glassx 14y ago> How many ways can a reasonable programmer write the factorial function imperatively This page is a terrible example. Most of these are not not what a "reasonable programmer" would do. An unreasonable programmer would be able to screw up on any paradigm. You'd probably have even more ways to screw up like this with an OO language, creating classes for recursive functions, trampolines, a pattern matching class, implement an language interpreter inside your factorial implementation, etc.
- verroq 14y ago> You'd probably have even more ways to screw up like this with an OO language My example was about imperative languages. You assertion on how many ways one could screw up on OO is irrelevant and besides, you'd really need a good understanding of OO to even try implementing those. I didn't mean to use to imply any of those methods were bad. I have revised my post so people can't miss the point. That is > It is unfortunate when your ability to program functionally is directly proportional to how much of the standard library you have memorised. This makes functional programming much harder to learn. Now, addressing your concerns. > This page is a terrible example. Most of these are not not what a "reasonable programmer" would do. All of the examples except for few particularly egregious ones seems reasonable to me. For example -- one, need n+k patterns but so what fac 0 = 1 fac (n+1) = (n+1) * fac n -- two fac 0 = 1 fac n = n * fac (n-1) -- three fac n = foldl (*) 1 [1..n] -- four facs = scanl (*) 1 [1..] fac n = facs !! n -- five fac = foldr (*) 1 . enumFromTo 1 -- six fac n = product [1..n] Six fairly distinctive ways. I'm sure there's more that's as elegant if not more elegant ways to do the same thing.
- jwdunne 14y agoAfter the first 2, the rest are based on common and very useful abstractions. You could translate those to an OO language quite easily too, though with a lot more code. For example, what foldl does, from my understanding, is to recursively apply a function to both a starting value and the first element of a list, and then the same thing again, where the result from the last call becomes the starting value and the rest of the list becomes the list we're working on, up until the list is empty. Not sure if I've explained this well but I've not been into this long. If you see the second function, that's what it's doing, except it's working just with numbers and not a list. Since foldl works on lists, you need an enumerator, which in this case is just 1 through to n. The sixth example is great here. Product could easily be an abstraction on something quite similar to three, which itself could very well be an abstraction quite similar to two (using lists, functions to deal with lists and a given function). Please correct me if I'm wrong at any point here. I'm looking to improve these skills quite a lot so it'd be very, very welcome.
- gphil 14y agoI'm interested in how this turns out. Note that: As of June 21, 2012, only the first chapter is complete.
- will_work4tears 14y agoI was going to purchase this but saw this fact and stopped myself. I get what the author is trying to do, but I'm not going to buy a book before it is completed. Especially with an unknown (to me) author. It's like trying to sell me the Brooklyn bridge before it is even built.
- mvzink 14y agoHow do you think the Brooklyn bridge got built?
- will_work4tears 14y agoI'm guessing the city built it with taxes. Probably without needing a public vote. I could be wrong though, I'm not from that area. Certainly not some guy on a virtual street corner asking for what amounts to donations.
- yawn 14y agoThis is actually advocated by the "lean" startup movement. I've read a couple of books that advocate putting "buy" buttons on content/applications that do not yet exist to gauge demand or test potential ideas. I get it, but it doesn't sit right with me.
- nickknw 14y agoTo anyone who hasn't, I recommend downloading the sample PDF - the available first chapter is a decent size and a great read. I am looking forward to seeing the rest of it! Here's an excerpt: I’ll start by teaching you just enough Clojure to be dangerous. Then we’ll use that knowledge to embed an object-oriented language within Clojure in a more-or-less conventional way. Now if that doesn't sound like an exciting start I don't know what does.
- wellpast 14y agoI've been looking for more of a direct comparison of OO vs. FP with side-by-side examples. I think there are a lot of specific but concise examples for demonstrating the two paradigms. I tried to do a little bit of this in a recent post: http://news.ycombinator.com/item?id=4154484 http://news.ycombinator.com/item?id=4154484 Would be interested to hear of any other resources that do something similar -- that show specific OO code and corresponding functional takes on the same code. I find that a lot of the discussions avoid getting down to specifics, with code.
- ufo 14y agoThe problem is that often there is no direct analogy. And even when there is an analogy, often they behave differently as far as modularity and extensibility are concerned. OK let me be more specific (keep in mind that I am a little bit Haskell-minded right now so some of my examples apply to generic FP but some are more for Haskell): As far as encapsulating state goes, you have objects in one side and closures in the other. Pretty straightfoward, if you see it in practice. As far as control-flow goes, things are kind of very oposite. FP languages tend to use pattern matching (that is, switch statements / the observer pattern) on transparent types to do branching while OO languages settled to use message passing over opaque types. These two approaches are very much opposites - pattern matching makes it easy to add new functions and harder to add new "cases" and also forces types to be transparent. OO dispatching on the other hand, makes it easy to add new cases (classes) but makes it harder to add new methods. The objects are also opaque and encapsulated. (For more on this, search for the "expression problem") As far as polymorphism goes, things tend to be pretty different. OO languages focus on subtyping, writing code that works seamlessly with a class and its subclasses. This is good for always being able to add new subclasses without breaking old code. FP languages, on the other hand, tend to focus more on parameric polymorphism (generics, that is, writing code that doesn't care what types its manipulating) and Haskell handles ad-hoc polymorphism with type classes. Type classes are kind of like OO interfaces, but they allow type classes to be created after the types that "implement" them but do not allow you to turn previously monomorphic code into polymorphic code (so its kind of the opposite of OO in this sense). ---- Finally, if you are willing to go really academic on this, you can check out things like Cardeli's "A theory of Objects". Computer scientists inevitably end up translating everything back into the functional calculi they are confortable with and this leads to formal FP-to-OO translations, if that is what you are looking for. Just to warn you though, it turns out that some things like support for inheritance and dynamic dispatching can seriously complicate the final models.