[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

C vs. Lisp



    Date: Mon, 21 Jan 1991 20:07 EST
    From: gooch@TIJERAS.SW-SW.Dialnet.Symbolics.COM (William D. Gooch)

    ... I think all this debating
    over Lisp versus C might simply fade away if some of the vendors would
    get their act together and provide a truly integrated approach to the
    cooperative use of multiple languages in their software environments.
    Unfortunately, this is difficult to accomplish in Unix. ...

The vendors (both Lisp and C) would have to talk to one another.  This
can't be done in isolation.  With my language designer's hat on, let me
add some perspective.  [Standard disclaimer:  Just my personal views;
not necessarily those of Symbolics, etc.]

It is clear that interoperability with other languages has been
historically neglected by Lisp.  Some of that has changed, continues to
change, and might or might not need to change more; but let's leave that
aside for the moment.

I believe no language (or vendor) can unilaterally solve the problem of
inoperability.  To call another language invisibly, you must offer its
data structures and it yours.  If that is not true, then special
communication data structures must be conjured and those structures will
not, in general, have the same properties as the structures you're
familiar with.  Consider how many times you've heard people talk about
Lisp strings, C strings, Pascal strings, etc.  even in languages that
can supposedly talk to one another.

The fact that C has no representation for an integer (by which I mean a
number which monotonically increases as you add 1 to it) is another
extremely frustrating example.  It's nice that it has more efficient
representations of numbers, but then, Lisp does to.  Linguistically in
Lisp you can already say "this is a number between 5 and 37".  It
happens to be that some compilers don't do anything with this
information, but that's just a bug in those implementations and not a
bug in the language.  (This distinction may not be of practical use to
programmers on a day-to-day basis, but I think that it is important
philosophically.)

A similar truth occurs in control flow.  Condition handling, etc.
is radically different among languages.  For example, this thwarts 
the ability of a program to cross-call another program and manage 
errors in a uniform way.  Mechanisms can be devised to hide some of
this, but the mechanisms are, at this point in time, implementational,
not linguistic.

Because languages are permitted to say they support things when they
really don't (e.g., integers) merely by picking names which suggest
support without providing it, I think leads to much of the trouble.
It means that it's very hard to compare languages apples for apples,
because there is no standardized terminology for the comparison.

In addition to control flow and data structures, conventions for passing
data from point to point varies; Lisp uses `call by value' to mean something
very different than PL/I does, for example.  Some languages provide `call
by reference', `call by value return', etc. and others do not.

Subroutine library pools will never really be sharable across languages
unless things like data structures and control structures are fundamentally
the same, so that the nature of the calling languages is irrelevant to the
action of the subroutine. [Even the term subroutine means different things
in different languages; I'm speaking generally.]

As an aside, in motor vehicle traffic law, I once noticed that there is
a document called the Manual Of Uniform Traffic Control Devices.  The
Massachusetts General Law refers to this document by inclusion, and I
suspect that others do as well.  The manual says things about what it
means to have a flashing yellow light, or to have a solid red, or a red
flashing walk light, or whatever; and then the law just says `we support
that.'  That way, even though laws vary from state to state, it is never
the case that you find that flashing yellow means one thing in one state
and another thing in another state.

If we are ever to solve the problems of interoperability, we need an
external source of a checklist (a Manual Of Uniform Linguistic Features)
which assigns names to all linguistic features so that (a) you can
compare on an even plane what features are supported by languages and
what are not and (b) you can cross-call between languages when the level
of support you need on both sides is the same.  [Easier said than done
perhaps; it might have the same problems that mixins have in Flavors/CLOS
with certain features influencing certain others.  So I'm not saying it
would be easy to do; but even if it would be hard, I hope it's not hard
to understand the goal.]

It is my belief that terminology needs to be pinned down in a
language-independent way and everyone needs to agree to adhere to
standard naming.  Note that I'm not suggesting changing what any
language actually does, if the language designer is happy with that.
I'm just saying that there is a real tower of babel in the community
because everyone uses the same term over and over for different
purposes, and they're surprised that things don't line up.  If everyone
were forced to use distinct terms for processes and structures which
were legitimately distinct, it would be obvious how few things in the
world are even superficially compatible, and we'd be grateful that
there's as much compatibility as there is... or maybe we'd start to work
harder on really making things compatible for real in later generation
systems.

Interoperability will really be possible when you can just say:  `ADD1
is a function which receives an integer argument and returns by value
the integer which is its successor' and know that you've left nothing to
chance, regardless of the language involved.

And until you have that, then you are forced to go through compatibility
packages. And every time you do, it means you can't use the native data
structures of your own dialect.  Which means that you're likely to be
hampered any time you want to cross a language boundary, no matter how
good the compatibility package is.  So the tendency is often for people
to choose one language and just stick to it even though intuitively you
would expect people to just use each language for the parts it was good
for, and rely more heavily on the compatibility packages to glue it all
together.

So I come back to my original point.  Even if Lisp added every aspect of
C, it could not transparently call C because it would have to worry that
some Lisp thing that C didn't understand would slip through.  Neither
could C unilaterally decide to support all of Lisp in order to induce
compatibility, because it would still have to worry that it couldn't
pass C-only things through the portal.  The effect can only be achieved
by negotiation, and no negotiation that I'm aware of is ongoing.  I
think that's sad.

I had other points I wanted to make, too, but this is running long so I
guess I'll save them for another day.