Subject: Re: Which one, Lisp or Scheme?
From: Erik Naggum <erik@naggum.no>
Date: 1997/01/30
Newsgroups: comp.lang.lisp,comp.lang.scheme
Message-ID: <3063644148416167@naggum.no>


* Earl Esharris Daniella Harris
| IMHO, CL looks like it is much harder to master the Scheme.

FWIW, I found the opposite to be true.  my favorite example is `member',
which Common Lisp calls `member', but which Scheme calls `memq', `memv', or
`member' according to which function should do the testing.  in Common
Lisp, I can choose the test function with :test, and use `eq', `eql' or
`equal' as I see fit.  should I want a different function, such as
`string-equal', I can use that, too.  in Scheme, I must implement my own
`member' with `string-equal' as the predicate.  in practice, I implement a
new `member' (which must be called something other than `member' since
Scheme doesn't have packages and redefining isn't kosher), which takes a
function as argument.  in like manner, I must reimplement everything else I
need with a higher level of abstraction than Scheme provides.  I have
concluded that Scheme is a pretty dumb language as standardized.  had all
of this hype about functions as first-class arguments been true, wouldn't
Scheme have used them more often, I wonder.

| If you need to understand pattern matching to master CL, this is one
| strike against CL.  Scheme doesn't have this; it isn't necessary.

you don't need to.

| If you need to understand tuples and structures to master CL, this is one
| strike against CL.

you don't need to.

| Are values a new data type in CL?

no, all functions return multiple values in Common Lisp.

| If you have to learn and differentiate between several DEFs, this is a
| strike against CL.

you need to know only `defvar' and `defun' to get going.

| While scheme has essentially "define," Common Lisp has several
| "DEFsomethings".  Why does Common Lisp have some many definitions?

(1) because Common Lisp recognizes that a single namespace for functions
and variables is bad for you.  (2) because Common Lisp has features that
Scheme does not have.

`defsetf' was mentioned.  in Common Lisp, if you have a function (foo x)
that returns some piece of information, the typical function to make that
function return some new value known by your program is (setf (foo x)
new-value).  e.g., if you retrieve elements from an array with (aref A i),
you store a new value with (setf (aref A i) x).  in Scheme, you use
specialized functions to access different kinds of arrays, and you must use
different functions to store values into them, too.  you define your own
setf methods (or "setter functions") with defsetf.  you can also define
them with (defun (setf foo) ...) just like other functions.  I find this
very elegant, and certainly much more so than functions named `set-foo!'.

| If you need to understand "meta classes" to master CL, this is also one
| strike against CL.

sigh.  you don't need to.

| If you need to understand several flags and options in the print
| functions, this is one strike against CL.

sigh.  you don't need to.

| Regarding the evaluation model, CL's doesn't treat functions as first
| class objects.  I can't pass functions around like other values (numbers,
| lists, etc).

you should have asked a question.  the above is as untrue as you can get.
however, functions aren't normally values of variables.  this is seldom as
useful as Schemers think it is.  the only difference between Scheme and
Common Lisp regarding functions is that in Scheme the first element of an
expression is evaluated like the rest of the elements, whereas in Common
Lisp, it is evaluated specially.  evaluating a function call form in Scheme
means (apply #'funcall (mapcar #'eval form)), except that Scheme is allowed
to evaluate arguments in any order, whereas in Common Lisp it means
(apply (car form) (mapcar #'eval (cdr form))), keeping with Common Lisp
syntax in both cases for the sake of comparison.

| However, IMHO, it is hard to defend that CL is easier to master than
| Scheme.  Just compare the reference manual size.

Scheme is a relatively low-level Lisp.  you _can_ build tall abstractions,
but you run into many serious problems in scaling, not to mention the fact
that Scheme is a language of bare necessities, like living in a cave, while
Common Lisp is a language of complex societies where all the infrastructure
you want to take for granted is indeed already implemented.

however, I can sympathize with you on the cognitive level.  Common Lisp
seems large and unwieldy.  let me illustrate with an anecdote.  I moved to
California to work on a project and stayed for five months.  when I first
got there, I found that I experienced cognitive overload in supermarkets.
this was the first time I had had to buy my own groceries in the U.S. and
was not at all used to the variety or the brand names or anything.  there
were dozens of different maple syrups, a hundred kinds of bread, etc.  back
home in Oslo, there is much less variety, and some stores even specialize
in having a small number of products, like 800.  gradually, over many
years, I had come to choose around 40 different products that I bought on a
regular basis.  I could shop sleeping.  however, in California, my nearest
supermarket was quite small by U.S. standars, and offered only 3000 or so
different products, none of which even looked like what I was used to.  it
dawned on me after having become quite tired of the first couple shopping
experiences that I had tried to take in all of them at the same time, that
I had no grounds for comparisons, and that I still didn't think in dollars
so I didn't even have a working economic model to fit things into.  in
response to this cognitive overload, I systematically went through a small,
new section of the store every time I went there, after I had found a
subset of their products that I could eat.  it still took two months before
I had a working knowledge of brand names, product categories, price levels,
etc.  however, my point is that although I recognized a problem in my
approach to something new and very large by my standards, I didn't starve
while I tried to sort out which maple syrup to pour on which breakfast
waffles with which fruits on it.  (I learned later that I had skipped the
best maple syrup, too.)  when I got home, I had acquired a taste for the
variety, and found myself buying at least 5 times more kinds of goods on a
regular basis than I used to.  if you like, Scheme is like a bakery that
produce three kinds of bread according to clearly specified nutritional
models, while Common Lisp is like a supermarket with baked goods from a
large variety of bakeries.  once you enjoy the variety, you won't find the
bakery confined to "only what's good for you" to be much of a treat.

it may be worth noting that I had already become really annoyed by C's and
Unix' lack of useful functions and all the manual work that was necessary
to get even simple things done.  (such as: in a system-wide shell init
file, you need to set the search list (path) for interactive shells.  it is
important that a few directories be present for all users, but their order
is immaterial and may be chosen by the user.  if some directory is not
present in the search list, it should be made the new first element of the
sublist that contains only elements from the required list, in other words:
it should be added before any other required directories, but after any
that the user might have set up.  exercise: do this in the various shells,
in Scheme, and in Common Lisp.  for extra bonus points, do it in perl.)

#\Erik
-- 
1,3,7-trimethylxanthine -- a basic ingredient in quality software.