[comp.lang.misc] Unification of Paradigms

norman@a.cs.okstate.edu (Norman Graham) (09/19/88)

Has anyone out there tried to derive a set of concepts that would 
allow the unification of procedural, object, functional, and logic
languages?  I've kicked the idea around a little and there doesn't
seem to be a whole lot of difference between the lot (although I've
done very little logic programming).

First let's start with a suitably powerful procedural language (ie.
an orthoganal language that includes both functional polymorphism
(true polymorphism) and overloading (ad. hoc. polymorphism); functions
as data objects (allowing for functionals); first class citizenship
for all objects; etc.).  Now if we give programmers the option of
specifying that a function does not use a store, doesn't that allow
a program (or selected parts of a program) to be built using the
functional paradigm with all of its advantages?  Futhermore, it
seems that the only difference between this language and an object
language is packaging (eg. do we package the functions as part of 
the object or not?).  I've left out inheritance, but perhaps it fits
in as well.  Logic languages only seem to provide syntatic sugar
for a handful of functions easily written in the above language.
|-: Don't flame me for that last statement.  If it's incorrect
just write it off as a statement by a logic programming novice and
explain why it ain't so. :-|  Granted, a language like the above
would not set the world on fire with its speed on machines using
today's conventional architecture, but...

If you've had similar ideas, or ideas to the contrary send mail.
If you have a flame send mail also (this group is already too 
cluttered with flames).

Thanks for your support...

--
Norman Graham
Oklahoma State University              Internet:  norman@a.cs.okstate.edu
Computing and Information Sciences         UUCP:  {cbosgd, ihnp4,
219 Mathematical Sciences Building                 rutgers}!okstate!norman
Stillwater, OK  74078-0599

ok@quintus.uucp (Richard A. O'Keefe) (09/21/88)

In article <3923@okstate.UUCP> norman@a.cs.okstate.edu (Norman Graham) writes:
>Has anyone out there tried to derive a set of concepts that would 
>allow the unification of procedural, object, functional, and logic
>languages?

I don't know what PopLog does about objects, but it has been integrating
imperative (Pop), functional (Lisp, ML), and logic (Prolog) programming
for quite some time.  Lisp itself (if we take this to mean Common Lisp
+ CLOS) integrates imperative, functional, and object-oriented programming
rather smoothly.

>Logic languages only seem to provide syntatic sugar
>for a handful of functions easily written in the above language.
>|-: Don't flame me for that last statement.

Why not?  If you know that you don't know much about a subject, why
pontificate about it?  If Graham's exposure to logic programming has
been to Turbo Prolog, then he has some excuse.  There are operations
which can be done in O(N) time in a logic programming language which
require O(N.lgN) time in a pure functional language, thanks to the
logical variable (basically, information can be propagated
instantaneously throughout an arbitrarily large data structure, just
as by conventional assignment).

Logic programming languages (and the special case, functional languages)
can express *inheritence* quite easily; where they part company with
object-oriented languages is that they cannot handle the notion of an
*object* having an identity which is distinct from its state.  (There
is an object-oriented style used in Concurrent Prolog, but the "objects"
are abstractions of states of processes, having existence only in the
programmer's mind.  Programs manipulate message streams.)

shankar@srcsip.UUCP (Subash Shankar) (09/21/88)

In article <3923@okstate.UUCP> norman@a.cs.okstate.edu (Norman Graham) writes:

>in as well.  Logic languages only seem to provide syntatic sugar
>for a handful of functions easily written in the above language.
>|-: Don't flame me for that last statement.  If it's incorrect
>just write it off as a statement by a logic programming novice and
>explain why it ain't so. :-| 


Logic is not merely syntactic sugar on top of functions.  First, unification
is much more general then function invocation, for obvious reasons.  This
gives logic added expressive power.  Second, a logic predicate is reversible
(i.e. it can be "solved" for any combination of arguments bound), while 
functions have prespecified input and output arguments.  Again, this adds
expressive power since in the worst case you would need 2^n functions for
each logic predicate where there are a total of n inputs and outputs.
 
Finally (although I'm sure there are other reasons around), the nature of 
the logical variable is more amenable to lazy evaluation and other such
niceties.  

Now, if you were to say that functions only provide syntactic sugar for a
handful of predicates written in logic languages, I would probably agree :-)

norman@a.cs.okstate.edu (Norman Graham) (09/21/88)

From article <8943@srcsip.UUCP>, by shankar@srcsip.UUCP (Subash Shankar):
> First, unification
> is much more general then function invocation, for obvious reasons.

I did not have in mind the replacement of unification with function
invocation.  I was thinking of unification as a function from
assertions and goals to answers.  

Of course, what I intended in the original posting was to incorporate
basic ideas from other paradigms into the paradigm that I'm most 
comfortable with (ie. procedural).  I've only now become aware of that 
intention, and can now see the blind spot that it caused.  (Incidentally,
I am saddened by the crippling of procedural languages by static
type systems; lack of first class citizenship for all objects; 
inability to specify things such as lazy or eager evaluation,
the environment to operate in, and to use a store or not; and the 
lack of higher order type systems.  The current procedural languages
can be extended a great deal before they cease to be procedural.)
 
> Now, if you were to say that functions only provide syntactic sugar for a
> handful of predicates written in logic languages, I would probably agree :-)

You may smile, but you raise a case that I had not considered.  Now it
looks like we have four choices:

1) function invocation and unification exit as independent concepts,
   side-by-side in the language.

2) functions are implemented as some sort of restricted unification.

3) unification is implemented as a function.

4) function invocation and unification do not exist in the same language.


In the future, I'll take O'Keefe's advise and not pontificate about
topics I know I know nothing about.  But since we're already going
on this topic, let's beat it around a bit.

-- 
Norman Graham                            Oklahoma State University
  Internet:  norman@a.cs.okstate.edu     Computing and Information Sciences
      UUCP:  {cbosgd, ihnp4,             219 Mathematical Sciences Building
              rutgers}!okstate!norman    Stillwater, OK  74078-0599

ok@quintus.uucp (Richard A. O'Keefe) (09/23/88)

In article <3938@okstate.UUCP> norman@a.cs.okstate.edu (Norman Graham) writes:
>I am saddened by the crippling of procedural languages by static
>type systems; lack of first class citizenship for all objects; 
>inability to specify things such as lazy or eager evaluation,
>the environment to operate in, and to use a store or not; and the 
>lack of higher order type systems.  The current procedural languages
>can be extended a great deal before they cease to be procedural.)

(1) First-class citizenship for all objects:  there are _very_ few programming
    languages which really make functions first-class citizens (that is,
    define equality on functions as is standard in 2nd-order logic).
    I do know of two, but I can't remember their names.

(2) Lazy evaluation:  lazy evaluation is fine, and side effects are fine, but
    if you combine them in one language you are going to have troubles.  See
    Peyton-Jones' book for examples of how hard it is for a human reader to
    tell whether a function will be lazy or not.  (Try programming with
    Pop-2 "streams" -- lazy lists -- some time.)

(3) Higher-order type systems:  you have to be _very_ careful if you want
    type-checking to be computable.  Martin-Loef's "Type Theory" is a
    programming language!  (type=set=proof=program)

They're all nice features, but putting them together and making the result
compile fast, run fast, and use a small run-time library is far from easy.
There is still some excuse for C.

>1) function invocation and unification exit as independent concepts,
>   side-by-side in the language.

I'm not quite sure what's meant here.  Prolog, for example, hasn't got
functions, only predicates.  There are several proposals for extending
Prolog with evaluable functions, generally based on demodulation or on
narrowing, which amount to building function invocating into unification.

Apart from the lack of any kind of static type checking, PopLog seems to
come close to Graham's requirements.  Then there are things like Eiffel.