Subject: Re: Which one, Lisp or Scheme? From: Erik Naggum <email@example.com> Date: 1997/01/30 Newsgroups: comp.lang.lisp,comp.lang.scheme Message-ID: <firstname.lastname@example.org> * 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.