Functional/Object Oriented Evolution

Posted by Daniel Lyons Thu, 04 Oct 2007 02:27:00 GMT

I noticed something interesting the other day about the functional and object-oriented languages.

Consider Python, where you can write functions like:

def foo(first, second=0, *rest, **kwargs):
  return first + second / len(rest) * kwargs['multiple']

Compare to a functional language like Haskell, where you can’t do that, but you can create types like:

data MyThing = YourThing Integer 
             | AnotherThing (Int, Char, Float)
             | NoThing

Weird that in Haskell, a functional language, you don’t get keyword arguments or arbitrary numbers of arguments, but you do in Python, whereas in Python, you’re confined to a rather small set of built-in types or full-on objects.

Of course in Lisp, you get really ornate functions and the ability to make new types through OOP. But you don’t get strong typing. ;)

Tags , , ,  | 2 comments

Comments

  1. Avatar Bill Weiss said about 10 hours later:

    Your python example is really convoluted, you know that?

  2. Avatar Justin Dressel said about 19 hours later:

    Well the situation is a bit more subtle than that in Haskell. You can have arbitrary arguments using a homogeneous arbitrary length container, like a list. You can mirror keyword mapping using tuples or another data structure (or a static record type). So you could almost write your bizarre python function as follows:

    foo :: (Fractional a) => a -> a -> [a] -> [(String, a)] -> a
    foo f _ [] _ = f  -- avoid zero-division
    foo f s r k = f + s / rest * mult
      where
        rest = length r
        mult = case lookup "multiple" k of
                   Just n -> n
                   _ -> 1
    This is less compact certainly, but more importantly it’s missing three critical features of the Python code:
    1. No default second argument. You could rearrange the first two arguments and make closures corresponding to different defaults, but it’s not quite the same.
    2. The “rest” and “keyword” arguments are not optional. They must at least be specified as empty.
    3. The arbitrary length containers must be homogeneous in type!

    On the other hand, the Haskell code is better specified due to the strict typing and Maybe error checking.

    I think there are two fundamental limitations of expressiveness in Haskell that are more to the point:
    1. You cannot specify an arbitrary number of differently typed parameters. A generic “heterogenous n-tuple” or “heterogenous list” doesn’t exist. You can fake it with data structures for a finite number of possible type alternatives by making a wrapper type abstraction, but fundamentally it’s a limitation of the type system.
    2. You cannot define default values for parameters to a function, since expressions are only available when all parameters are received. This cuts down on some nice coding conveniences available in Python, but allows for all the other flexibility of the functional aspects of the language. I think that’s a fair trade.

(leave url/email »)

   Comment Markup Help Preview comment