views:

119

answers:

2

I was introduced to Clojure not long ago, and while I haven't fully assimilated all of it's concepts, It has given me an alternative to Java and PHP's OO that I really want to move towards. I consider Clojure's systems to be my ideal. I know that I want to let it inform my PHP coding style as much as I can.

I really don't like OO in PHP, I hate the amount of boilerplate and the hidden complexity that it often seems to lead to. At the same time, I can see benefits to encapsulation where you have multiple bits of data that carry the ability to modify themselves around. Maybe using 1st order functions is the main way to allow for that encapsulation, but beyond that how can the benefits of Object Orientation be translated into Functional Programming?

One part of the problem that I'm having now is how to deal with a collection of related functions that might otherwise be grouped in a class, in a sane way that keeps them useful to each-other.

+1  A: 

I don't know what features php has but as far as I know, passing functions around (and methods) is pretty horrible and there are like 10 ways to do it, so it will not be easy. For general advice, here is some standard stuff:

  • dont use classes unless you need hierarchies
  • avoid global stat
  • write functional layers on top of imperative libraries
  • define higher order functions to handle data (if that is possible)

I don't think PHP is good for FP. It's totally against it's 'design' philosophy. Best of all would be to avoid php all together but that isn't always possible.

nickik
+3  A: 

From Edward Garson's piece in the book '97 Things Every Programmer Should Know' in the article titled 'Apply Functional Programming Principles' he boils it down to:

Referential Transparency http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)

I think any OO language can be written with a functional style to some degree and I think the best way to think about it is to always be returning something. if you mutate a data structure, return a copy of the data structure with the mutation applied, don't change the original data structure. If you need to change state of an object, be very declarative about doing so. And finally, without being too specific, write unit tests for your methods, because it will force you to write more methods that are more focused in intent and when you have returns from those methods, they are much easier to test.

Jed Schneider
That sounds apt, I'm trying to figure out how to translate that into php terms.I think that I might order that book to read that section (and the other parts of it, which probably can't hurt).Unit tests is a great point, and one that I can essentially pursue without issue.The "don't change the original data structure" part seems kinda... ...tricky in php, since I think performing an action on an object generally happens by reference by default in php, though perhaps that's ok? Should I try to deep clone objects in order to return a completely new copy? And rely on garbage collection?
Tchalvak
my PHP is pretty bad but to answer your question, in a data structure, I would produce a copy, and then change the values of the array, like so: http://pastie.org/1075342 Arrays are not first class objects in PHP so its not quite the same, but the concept is. Again, the goal is to operate with as little state as possible, so the first question to ask is: Do I need an object?. I will have to leave the PHP implementations of that to you though.
Jed Schneider
Just to archive the pasted code for later reference: ` <?php $arr = array("foo" => "bar", 12 => true); $arr2 = $arr; $arr2[] = "test"; echo $arr == $arr2; #=> false echo $arr === $arr2; #=> false ?>`
Tchalvak