Showing posts with label Functional Programming. Show all posts
Showing posts with label Functional Programming. Show all posts

Monday, March 14, 2011

Functional and Object Oriented Programming

In the past, I've talked about integrating functional and object oriented programming. I still feel like that's a great way to produce clean code.

This article addresses a few more aspect of functional and object oriented programing, including Bottom up vs Top down design.

Object Oriented programming often encourages thinking about code in a top down way. On the other hand, functional programs tend to be bottom up. I've found this to be pretty accurate in the past when I work with both paradigms.

One particularly interesting point made in the article is about reusability. Specifically, the article claims that bottom up code is inherently more generic because they are built before their exact uses are explicitly planned and encoded. I've never really thought about it like that, but it makes sense. In general, functional languages provide you with a lot of resources to create cleaner, more reusable code. First-class functions are probably the biggest convince they offer for creating clean code. Of course, reusability isn't always the best goal anyway. Reusable code just happens to also have a lot of other very desirable properties. 

Sunday, February 13, 2011

Functional Programming In Object Oriented Development

In first year, we learned about functional programming. We learned about the evils of mutation, and the power of stateless programming. Unfortunately, everyone abandoned functional programming the second they got the chance. They picked Java (or C++ (OR EVEN C!)) instead of Scheme because they were more comfortable with imperative programming.

The problem is that most functional languages don't have great support for industry-strength development. They don't let you quickly build GUIs, or have built in support for design patterns. Granted they don't need a lot of support for design patterns, since the language itself makes them obsolete. All this really means though, is that functional programming languages shouldn't be your base language for your application. It is still a good idea to have small functional modules, or even better, to just code with functional programming in mind when you write your imperative code.

I realize that imperative and functional are somewhat conflicting paradigms. One revolves around modifying state, and the other tries to avoid it as much as possible. Like most things, it's a balance. Not every object needs to be mutable, and not every function needs to be recursive.

Here's a few things that I have found useful in imperative programing.

Immutable Variable
It really helps to have variables that don't change their values after initialization. If you need to change a variable's value, you can make a new variable. This makes debugging much simpler, and it's easier to think about your code. However, this doesn't always make sense in imperative programming. If you are making a counter, this obviously doesn't apply, and making counters the "functional" way is unintuitive. On the other hand, if you are modifying a string in several ways, several immutable variables might make sense:



Code like this is much simpler to test, since you can easily see the progress of the transformation of your string.

Immutable Objects
It makes sense for some object to be immutable. This applies well to plain data objects, or objects that simply aggregate related information. Immutable objects are inheritable thread-safe and simpler to code. You don't need to worry about coding complicated methods like clone (in Java). However, if you make every object immutable, you end up with really awkward looking object oriented code. Again, it's a balance.



Use Recursion
Some objects are naturally recursive, so it makes sense that operations on them should be recursive. This makes the code very natural. However, you shouldn't use tail recursion in imperative programming. You are essentially writing an awkward for loop. In fact, some compilers will optimize tail recursion and for loops into the same thing.




Avoid side-effects
Functions that don't modify state are much simpler to think about. They also make multi-threading those functions much simpler, since you minimize the amount of ways to change values. This is a hard rule to follow gracefully in a paradigm that revolves around methods changing state. The key is that not every function needs to change state. You have to choose side-effect free methods carefully. Static functions are usually great candidate for this.


Referential Transparency
This is just a fancy word for a function that doesn't depend on anything other than it's parameters. If I call the function with the same parameters, I should get back the same result, regardless of the outside circumstances. Writing functions like this makes threading much simpler, since these functions don't depend on outside state. Functions like these are also very simple to test since they don't have any external dependencies.


These are just a few things to keep in mind when you are writing code in object oriented code. It'll make your imperative code much cleaner and simpler to code, test, and debug.

</somewhat productive>
<Watching Troll 2>