Higher order versus Object order

Without wishing to cause a flame war, ..., well actually I do wish to start a discussion ...:)

For the last 25 years I have been working on programming languages roughly in the logic programming/functional programming paradigms.

About 10 years ago I embarked on a research trajectory involving moving from Prolog's 'meta-order' approach to a higher-order approach.

The reasons were technical: meta-order sucks from a software engineering POV.

However, recently, I have changed my mind. Or rather, changed direction.

While robust, HO does not deal with OO programming all that well. (Start flame wars here)

The reason is that OO involves combinations that are difficult for HO styles of programming.

On the other hand, OO does nearly everything that HO can do. I would argue, that at a slight loss of elegance, OO does *everything* that a good software engineer wants to do.

My reasoning is based on the fact that an object can act as a kind of closure but a closure cannot capture the multiple uses of an object - together with the interface contract.

BTW, as far as I am concerned, OO is *not* equivalent to inheritance+subtypes+methods+classes+instances. Those are techniques useful in some situations.

For me, OO is fundamentally about encapsulation and interfaces. The rest is noise (in my opinion of course)

So, in my most recent work, I am throwing out my HO implementations and replacing them with an Object Order implementation....

Comments?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Objects or Modules?

Francis McCabe: For me, OO is fundamentally about encapsulation and interfaces.

In which case it sounds like you're talking about what the functional community would call modules, in the sense of the SML or O'Caml module systems. More recently, research in type theory has blurred the distinction between module systems and object systems in exactly the way it sounds like you want to; see the various papers around Scala to see what I mean, especially "A Nominal Theory of Objects With Dependent Types" and Odersky's "Types for Objects and Modules" talk.

Scala

From what I know of scala, I quite like it. My interest is in logic-based languages -- not Java based languages.

either/or?

I would argue, that at a slight loss of elegance, OO does *everything* that a good software engineer wants to do.

There are three sliders in this sentence: one marked "loss of elegance", one marked "does *everything*" and one marked "good software engineer". It might be helpful to know just where those sliders are set.

In Smalltalk or Ruby or Python you don't have to choose, of course. Functions / blocks are objects. Function composition is object composition, of a kind.

I can't think offhand of a "combination" that is easier in OO than in HO. I had thought that rather the reverse was true. Composability is not what I would consider a strong point of most mainstream OO languages. Do you have any examples of the kind of thing you mean?

Combinations - a clarification

I dont mean combinators!

My intent is closer to the classic notion of combining separate entities into a single package.

BTW, IMO, the SE case for this is interesting: OO packaging allows one to modify the contract (a.k.a. interface+semantics) in a way that minimizes the impact on non-affected uses of the package. This is a simple idea, but essential in a world of changing programs and where the number of uses of a concept is >> the size of the concept definition

No ADT in FP?

OO packaging allows one to modify the contract (a.k.a. interface+semantics) in a way that minimizes the impact on non-affected uses of the package.
Could you elaborate?

Is ADT concept unavailable in FP?

The purpose of a ninja is to flip out and kill people.

Without wishing to cause a flame war

HaHaVeryFunny

While robust, HO does not deal with OO programming all that well.

I had thought that the point of programming was to write programs, and not to do OO.

On the other hand, OO does nearly everything that HO can do... BTW, as far as I am concerned, OO is *not* equivalent to inheritance+subtypes+methods+classes+instances. Those are techniques useful in some situations. For me, OO is fundamentally about encapsulation and interfaces.

The great thing about OO is that you can define it to be whatever you want it to be, and everyone has a different definition. This way OO can survive even when criticisms are leveled against any of its putative incarnations.

I would argue, that at a slight loss of elegance, OO does *everything* that a good software engineer wants to do.

Yes, you are absolutely right! So, what is the most effective way to reeducate all those poor, misguided software engineers? :)

great, another OO definition thread

there's only one definining feature that is unique to OO (or at least originated with it), and that is inclusion polymorphism. Anything else is available in many different forms elsewhere.

I think it is a mistake to co

I think it is a mistake to conflate implementation or techniques with justification. inheritance, polymorphism, etc. etc. are nice tools -- but should not be confused with the motivation for OO programming.

For me, a primary motivation for looking at OO is that it helps in the programming process -- all the programming process.

Inclusion Polymorphism

Wouter: there's only one definining feature that is unique to OO (or at least originated with it), and that is inclusion polymorphism. Anything else is available in many different forms elsewhere.

And there's an argument to be made that inclusion polymorphism causes more problems than it solves.

sure

I didn't argue about its value. I personally prefer inclusion polymorphism expressed in different ways than just using inheritance, multimethods for example. Combining inclusion polymorphism and data structure extension/compatability in one mechanism just gives too many problems.

Encapsulation with closures

an object can act as a kind of closure but a closure cannot capture the multiple uses of an object

For me, OO is fundamentally about encapsulation and interfaces.

Scheme:

(define (mk-point x y)
  (lambda (op . args)
    (let
        (
         (get-x (lambda () x))
         (get-y (lambda () y))
         (add (lambda (pt) (mk-point (+ x (pt 'x))
                                     (+ y (pt 'y))
                                     )
                      )
              )
         (sub (lambda (pt) (mk-point (- x (pt 'x))
                                     (- y (pt 'y))
                                     )
                      )
              )
         (wr (lambda ()  (display "(")
                     (display x)
                     (display " ")
                     (display y)
                     (display ")")
                     )
             )
         )
      (apply (cond
              ((equal? op 'x) get-x)
              ((equal? op 'y) get-y)
              ((equal? op '+) add)
              ((equal? op '-) sub)
              ((equal? op 'display) wr)
              )
             args
             )
      )
    )
  )

(define pt1 (mk-point 1 2))
(define pt2 (mk-point 3 4))

((pt1 '- pt2) 'display)