Business vs Programming: A mindset
In the last few months my mind has been filled with some stories by Reinier and Alper about what keeps them busy. I’m especially interested in two of their topics, namely their problems with salespeople and the dead/rise of functional programming.
As some of you might know I have been a salesperson for 5 years at various stores and I think this gives you a different perspective whenever you walk into a shop and encounter some problems. For example, I am way more understanding when store personnel is unable to help me because of my inside knowledge of how shops (or franchises in particular) work. I explain more about this in this comment on a post of Alper. On the other hand I’m easily annoyed whenever a salesperson is unable to communicate with me on a normal personal level.
I had this problem here in the UK when I wanted to get a UK mobile SIM for use in my Dutch mobile phone. I know that my phone is SIM-lock free so I just walked into a Carphone Wearhouse (a.k.a. Phonehouse) and asked them what my SIM-only options were. The lady asked me if I wanted a phone, but I clearly stated that I just moved into the UK and already had a phone. Imagine the surprise I had when I asked her why the SIM did not work in my phone and she answered, “Oh, you need a UK phone for that SIM!”. The simple inability to think along with a customer and try to clarify some constraints had lead me to ever want to buy anything at the Carphone Wearhouse anymore.
The phone I had to buy
What does this have to do with Object Oriented Programming (OOP)? Simple: the difference between OOP and Functional Programming (FP) can be described the same way. I agree with most people that you can do anything (or maybe more) in a FP-language that can also be done in a OOP-language, but sometimes the bad service is just not worth the money. If we consider a FP-language to be a bad salesman and an OOP-language to be a good salesman, then writing a program in a FP-language has to include asking every possible question to the salesmen about the product or service you want to use. It includes thinking about every constraint the guy isn’t telling you and although you might get more value for money the personal risk just might be to high.
From this perspective I started thinking about a few simple rules derived from OOP-languages for salespeople that might help them in the customer relations:
- Take responsibility: One of the nastiest things to hear as a customer is that the issue is not the fault of the salesperson but of some other company (or worse: colleague). Though this might be true, it is of no interest to the customer. Consider your responsibility to the customer as a public method that the customer has to rely on. The customer does not care that you subdivided the task to others which happen to be unreliable.
A good example here is the case of delegation of the problem by the Apple Centre Lijnbaan (Rotterdam, Netherlands) to “some” service centre in a other town. What made this case even worse was the fact that this comment had no extra value to the customer who could not personally reach that centre. - State your conditions: I know that one of the obligations of the customer is to ask for certain constraints when deemed necessary, but this does not mean that a salesperson only has to think about the money. Even if a client (user) knows what he wants when he walks into the store, try understand the users intentions and clarify the constraints.
- Flexibility: Take a good example of the LJS Apple service centre, who go beyond the normal contract of having to repair a Apple product. Their open policy for choosing diagnostics and repair dates is like a API that allows for far more than what a normal user might need, but sure as hell helps people like Alper and Reinier who depend on their hardware on a daily basis.
I know that this is a simple list, but maybe this reasoning can help both the aspiring salesmen and the FP-supporters to understand that the basic concepts of OOP-languages DO provide a better service and in my opinion therefore a better value for money.
PS: Kathy Sierra probably put my point better than I ever could in “Too many companies are like bad marriages“.
Anonymous
March 13th, 2007Could you describe in more detail the correspondence of these rules to OOP-language features and why FP languages don’t follow these rules.
danb http://www.prairienet.org/~dsb/
March 13th, 2007> writing a program in a FP-language has to include asking every possible question to the salesmen about the product or service you want to use. It includes thinking about every constraint the guy isn’t telling you and although you might get more value for money the personal risk just might be to high.
Could you explain this section better? I don’t understand a word of it.
Cale Gibbard
March 13th, 2007Um, what!? I’m terribly sorry, but this argument is so non-sequitur and vacuous that I barely know where to begin to refute it, and the reasoning presented is so muddled that I’m not even completely sure it’s worth the trouble to do so, but I’ll give it my best shot.
The main problem with the argument is that the analogy is ill-formed. You don’t provide any evidence that FP behaves like a poor salesperson at all. Indeed, you’re talking about negative things which companies have done without tying them into programming practice in the least.
I’ll use Haskell in my examples, since it’s the functional programming language I know best.
Taking responsibility. There are many ways to approach how this ideal is reflected in the design of functional languages, but I think the most direct is via the use of types. Types are compiler-checked documentation of what functions require and produce. If functions may fail, this can be explicitly represented by types (e.g. Haskell’s Maybe or Either), allowing code to know up front that it will need to handle those failures.
Further, there are guarantees regarding which functions are able to have side effects in IO and which are absolutely not. Actions, which may perform IO, are marked as such. In all other cases, you get compiler-checked guarantees that these salespeople are honest and not allowed to go behind your back and communicate over the network, or read and write to the disk as they work. They are consistent, if they produce one result for a given input, they always produce that result. This is referential transparency.
To come closer to the OO side of this analogy you provided, specifically implementing public interfaces, we can require that in Haskell too, through the use of typeclasses. Not only that, but we can express much more complex dependencies — ways in which multiple types must cooperate to provide an interface. Then we can bound the polymorphism of functions based on those interfaces.
State your conditions — again, types, aside from comments available in essentially every langauge, provide an ideal analogy here. As type systems improve, more and more conditions can be explicitly proven by the compiler (type checking), and even generated for you when you don’t include them (type inference). In Haskell, as a very simple example, we can say:
sort :: (Ord a) => [a] -> [a]
This means that sort is a function which takes a list of values of an ordered type, and produces another such list. The implementation of sort is forbidden from explicitly examining the values of the list it is passed apart from making comparisons with ( b) -> [a] -> [b]
Map is a function which takes a function which takes values of type a, and produces values of type b, and a list of values of type a, and produces a list of values of type b. It does this in the obvious way by applying the function to each of the elements of the list. For the record, here’s an implementation:
map f [] = []
map f (x:xs) = f x : map f xs
This type signature will force the compiler to prove that whatever implementation is given for map, it cannot directly observe the elements of the list it is passed, and the only elements in the resulting list will be some elements from the input list which have had the supplied function applied to them. If map fails to apply the function to one of the elements in the list, but includes that element in the result anyway, then that’s a compile-time type error. For example, the following code will not compile:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = x : map f xs
As for flexibility, good APIs which act like embedded programming languages are what functional programming is all about. One doesn’t have to look far to see this. Libraries like Parsec for constructing parsers in Haskell, HXT for processing XML, and basically any monadic library you’d care to look at are good examples.
Anyway, this is a rather long comment, but I really want to give you some sense of why your line of reasoning doesn’t work, and possibly even get you interested in learning something about functional programming yourself.
Cale Gibbard
March 13th, 2007Hmm, part of my comment was eaten by your blog software. A non-mangled version of the comment is available from http://programming.reddit.com/info/19t5s/comments/c19tjl
Reinier http://zwitserloot.com
March 13th, 2007I think one of the points here was to highlight the need for a complete platform. I guess that’s a rant mostly against LISP, Haskell, and a few others, which work in just as large of a self-contained vacuum as e.g. java - it’s not so simple to interface haskell with other stuff in practice. Java gets away with not playing ball with other tools by being a massive effort with tons of APIs written just for it, and a lot of serendipity.
Alternatively this is a rag on python, ruby, and javascript, which due to their dynamic and objects-are-dictionaries approach, are fundamentally incapable of giving programmers support when they are using new libraries; no come-from, no auto-complete, etcetera. But, then again, it’s a very tough sell to convince anyone that things like Ruby on Rails aren’t programmer-friendly. They are too programmer friendly, some say, in fact.
Hani Al-Hasheeman
March 13th, 2007Java is the ultimate programming language. Why are these academics wasting their time on LISP, FORTRAN and PROLOG when Java is a complete, industry-standard, real-world platform??!
Cale Gibbard
March 13th, 2007“it’s not so simple to interface haskell with other stuff in practice”
Have you seen the Haskell FFI? It’s probably one of the best designed and lightweight foreign function interfaces I’ve ever seen. If that’s not enough, there are more automated tools on top of it. Most of the work in providing access to outside libraries from Haskell stems from the pickiness of Haskell programmers in library design. If all you want is direct access to a library, then that’s simple.
Check out the spec/documentation at http://www.cse.unsw.edu.au/~chak/haskell/ffi/ffi/ffi.html
It’s fairly tutorial in nature, and the whole thing is fairly simple.
wageslave
March 13th, 2007>> Why are these academics wasting their time on LISP, FORTRAN and PROLOG when Java is a complete, industry-standard, real-world platform??!
Because you need to be a masochist to enjoy programming in Java.
Cristiano Betta http://www.ibbydibby.com/
March 13th, 2007Wow, I thought my comment was on Salespeople. I assumed that everyone agrees that FP languages have their downsides, right?
Reinier http://zwitserloot.com
March 13th, 2007I know it’s easy to interface, and yet - write a webapp in haskell. Not quite as simple as just tossing some PHP into a folder and apt-get modphp. I dislike PHP as much as the next serious programmer, but that’s a valid point. Java is a similar giant pain in the arse to get set up right, and that’s what I was referring to when I said “in practice”.
Jim
March 13th, 2007You should be careful when advocating programming style A over programming style B, Cristiano. It’s like putting up a sign with “flamewar here” on the front page of your site - a good way to get traffic, though
However, you seem to be under the impression that FP and OOP are mutually exclusive. They’re not; there are many programming languages that are both functional *and* object orientated, such as OCaml, F# or Scala. FP and OOP are orthogonal concepts, so it makes no sense to say that one is better than the other.
Masklinn
March 13th, 2007> I assumed that everyone agrees that FP languages have their downsides, right?
Just as everyone agrees (or should agree) that OOP languages also have downsides, they’re just not the same as the FP languages, which doesn’t mean that some are inherently better than the others (I happen to much prefer FP languages and have less issues with their downsides than the OOP counterparts, especially Java).
And as Jim mentioned, OOP and FP aren’t completely mutually exclusive as some OOP languages are based on FP constructs (as opposed to imperative ones).
> FP and OOP are orthogonal concepts, so it makes no sense to say that one is better than the other.
I wouldn’t go *that* far, I’d say that the term “FP” takes up more “vertical” space, so part of “FP” is down there parallel to imperative (basic way to structure statements) and you can build OOP stuff upon it, and other parts are “up here” (application structure) and parallel to OOP.
Cristiano Betta http://www.ibbydibby.com/
March 13th, 2007@Jim: point taken…
Jim
March 13th, 2007Masklinn, OOP is essentially the technique of grouping code and data together in a container, i.e. an object. Conceptually, it doesn’t matter whether the code is imperative in style, like C#, or functional, like F#. Both C# and F# produce compatible .NET objects with comparable efficiency, which should be demonstration enough to show that OOP and FP are completely orthogonal concepts.
Masklinn
March 13th, 2007> which should be demonstration enough to show that OOP and FP are completely orthogonal concepts
Er wrong, it demonstrates:
1. That they’re computationally equivalent (which is perfectly true, it’s been demonstrated that lambda calculus — on which FP is based — is equivalent to the Turing Machine formalism — on which imperative & most OO languages are based)
2. That you can implement both an FP language (F#) and an OOP language (C#) on the same stack-based (mostly) imperative language (MSIL), which is not much of an imagination stretch as you can implement pretty much anything in anything else (including OOP languages in Logic languages, and FP languages in non-structured imperative languages)
It doesn’t in any way demonstrate that OOP and FP are orthogonal concepts.
Jim
March 13th, 2007Masklinn; like Java bytecode, and unlike x86 assembly, the concept of objects, classes, interfaces, attributes and so forth is built into the CIL. When I create a class in C#, that has a direct analogue in CIL. F# is no different; it produces the exact same class structures as C#.
This is because F# is an object orientated functional language. I can create classes and objects in it as easily as I can in an object orientated imperative language like C# or VB.NET. I don’t quite understand why you seem to think that OOP is tied to imperative code. OOP is merely a way of grouping together data and code; whether that code is functional or imperative is plainly irrelevant.
Paul
March 13th, 2007It doesn’t have to be all or nothing.
Believe it or not, you can actually use more than one language in a project.
Both OOP and FP have strengths and weaknesses. Hell, there is a lot to be said for AOP and procedural. Just use the best tool for the job at hand. If using more than one language in a project can allow you to use the strengths and avoid the weaknesses then why choose?
We can all have cake.