« The Cult of Language Expertise | Main | The Flawed Theory Behind Unit Testing »

May 28, 2008

Comments

Zhanyong Wan

Michael, I see that you have fixed the Haskell example (head tail
[1,2,3] => head (tail [1,2,3])). I guess you need to find another
example as there's no partial application (currying) here. :-)

One such example:

In Haskell we can write

contains a b
or
let x = contains a in x b

while using OO syntax we have

a.contains(b)
or
let x = lambda c => a.contains(c) in x(b)

which is quite awkward as you have to name the argument of the
anonymous function x. In other words, the FP syntax supports the
point-free style better.

maht

Just to add the other paradigm, stack style a la Forth :

c b a

James Iry

The syntactic difference only comes with a certain form of single dispatch OO. Of course, that form is by far the most common... :)

If you look at multiple dispatch OO there's no longer a single special argument that has the power of dispatch so it's more common to put the message name first. E.g. in Common Lisp's CLOS or Clojure you end up back with (verb noun1 noun2). Some would argue whether that kind of generic function is still "real" OO, but why get into it?

I don't know how the other hybrid languages you mention handle it, but in Scala you deal with partial application using an underscore. E.g. maht's example would be written in Scala as

val x = a contains _
x(b)

It's not quite as clean and as Haskell's - but not much really is.

Tom Faulhaber

There's another way to think about the partial function application than the simple prefix way.

Imagine your syntax supports this, for example:

let second = .tail.head in [1,2,3].second

This doesn't really give you currying (the "special argument" problem of OO still gets in the way), but it does give you composition.

Eric Larson

I always have considered OO somewhat organizational. The vast majority of the time I want functions that operate on objects, which are really just organization of data with possibly some dynamic rendering of the data. In this light, OO and functional styles are more interchangeable. I suppose this is also why I'm attracted to Python and JavaScript. Both languages do a good job of utilizing objects as data structures while allowing functional patterns.

Chris K

-- Haskell allows you to locally
-- define or redefine your own infix
-- punctuation, and the period "."
-- can be user defined as reverse
-- application. So this works:

twos = let a . b = b a
two = [1,2,3] . tail . head
second x = x . tail . head
two' = [1,2,3] . second
in (two,two')

-- This evaluates to (2,2)

Michael Feathers

maht: Thanks, but that first example was not meant to show partial application. It was just meant to show how traditional FP is a prefix style.

Michael Feathers

James: I'm aware of Lisp and multiple-dispatch. To me, it's really the neutral ground in the syntax space and a good place for a hybrid OO/FP language to be. We seed doomed to have these odd mixes like F#, Scala, and OCaml, however.

Michael Feathers

Tom: While I was mulling the idea of this post I came across that idea also and thought about posting it later. I've never come across a language which does that (although I haven't paid any attention to the concatenative ones). It does seem like a good feature, though.

Nat

I think this is because most *mainstream* OO languages don't let you deal with messages as objects. You have objects. You can send them messages. But messages themselves can't easily be manipulated.

The Higher Order Messaging technique lets you do partial application of messages but binds the partially applied message to a single object.

Gabriel C

More than the syntax, I think far more interesting are the *paradigm* differences between OO and FP. Particularly, how to arrive to a solution based on the description (or lack of thereof) of the problem

Paul W. Homer

Beyond syntax, at its heart OO is a specific model of the data, not unlike a type of lego blocks or even a subset of the tetris blocks (like the S ones). If you see the world as this odd-ball combination of static data and dynamic methods, that will influence how you try to jam it into a computer. If you see it as just syntax for disconnect variables that is a different perspective. From typedefs in C to vectors and matrices in APL, I suspect that the decomposition of data into primitives hugely effects how the problems are encoded by programmers. Mixing and matching is like having a conversation in multiple spoken languages all at once, extremely confusing to all but a very select group of people.

Paul.
http://theprogrammersparadox.blogspot.com

Sadek Drobi

Nice article! I've already talked about a relative point on my blog on

http://sadekdrobi.com/2008/06/01/and-you-get-all-the-vm-libraries-for-free-is-it-actually-what-i-want-when-i-switch-languages/

This post however treats syntax which is another important deffect of a the promise of a seamless integration.
Thanks Michael

The comments to this entry are closed.