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.