ram+@cs.cmu.edu (Rob MacLachlan) (02/18/91)
Subject: Re: In defense of call/cc (and a plug for T) Date: 16 Feb 91 10:21:04 GMT >PS. My own personal gripes with CL are [1] the type system is far too loose >[2] user-defined types aren't guaranteed to be distinct from previous >types [11] type assertions >are unchecked & are effectively promises rather than hints (I'd like both, > thanks). I think that you are to some degree confusing current implementation practice with what is necessarily so about Common Lisp. It is true that Common Lisp very rarely guarantees that errors will be detected (although in the ANSI standard, this does happen.) But implementations are encouraged to detect errors wherever possible. This would be an academic distinction were it not for the fact that there is now an implementation of CL that is strict about types, namely CMU CL. I think that the CL type system is great, what is a loss is the previous implementations of it. By default, the Python compiler for CMU CL checks all type assertions. Type checking (and other error checking) can be suppressed by the compilation policy specified in OPTIMIZE declarations. This means that you can write programs with declarations, getting the benefit of automatic checking of type assertions. In code that is performance critical, and that you are confident of, you may turn off type checking (though due to level of type check optimization, this may only get you 20%) In addition to the basic type assertions given for efficiency reasons (such as SIMPLE-STRING, FIXNUM), type assertions such as (OR NODE (MEMBER :END)) are also useful (and checked precisely.) Python also gives compile-time type warnings when its extensive type inference detects code that cannot execute without an error. > [3] equality doesn't work the way it does in other lisps & is >a nasty source of problems (e.g. portability) Meaning what? People are definitely unstatisfied with EQUAL and EQUALP, but fixing it right in this round seemed too difficult, so they punted. >[4] there's no multi-threading Yes, this definitely seems to be necessary in a viable lisp product. Both Lucid and Franz have it, and we are planning it for CMU CL. This is all within a preemptive lightweight-process model, like stack groups. I think that there is hope for standardization on this once people realize that you can have lightweight processes without having to discover the solution to expressing parallel algorithms. Stack groups are used for multiple concurrent interaction activities, not parallelism. As to CALL/CC: it is elegant, and seems to be useful for some purposes, but it doesn't address the same problems as stack groups. You need preemptive scheduling, and this means that you need synchronization primitives. A somewhat different ball of wax... >[5] I don't like keyword parameters/optional parameter etc and dislike >paying a cost for a feature I don't use Well, I agree that optionals are mostly a loss, but you shouldn't be paying any penalty other than compiler complexity. I am convinced keyword args are a big win for complex interfaces. Positional arguments start to lose it above 5 or 6 arguments. And keywords allow you to build general functional interfaces, as in the generic sequence functions. When combined with good inline expansion and constant-folding (as in Python), you get inline code as tense as any you could get from LOOP, etc. Python has no special magic for the keyword-accepting list functions such as MEMBER, we just make the inline expansions avaliable. >[7] the lack of temporary (transparent) hash-tables >(c.f. Poplog CL, T) [8] the lack of destroy actions (c.f. Poplog CL) Weak pointers and finialization are a win, and I expect you will see them in more CL implementations. CMU has weak pointers. >[12] the lack of a updaters (see Pop11) for an update >model that can support abstraction (SETF is a compile-time thing). I think that SETF functions address this issue. It would have been nice if they had gone with them from the beginning. > >On the other hand, CL gets my thumbs up for {1} putting lexical binding >on the map once and for all {2} its excellent number model {3} the Yes to lexical binding and numbers. And with CMU CL, I think that serious number-crunching is starting to become a real possiblity in CL. >size of its library (implementations all too often are sloppy in doing >this, see Poplog CL for an implementation that avoids dragging in every bit >of code (even the different cases of FORMAT are separately loaded)) which >I suppose could be better thought out Part of the problem here is that most Unix'es are stuck with crude VM technology. If you have a good VM system, having *everything* in one huge mapped file really works pretty well. Auto-loading is just slow software demand-paging with no ability to page out. It is possible that the VM locality might be better, but with good system building tools, the locality of a mapped system can be reasonable as well. Running under Mach has made us rather complacent about this, since a 24 meg program can start up instantly. >{4} for (mostly) successfully uniting >the Lisp community behind a single Lisp. I also think this is quite important. There is a positive role for standardization in technological progress, even though most standards are technically obsolescent by the time they are ready. I think that CL will have a longer life than many expect due to the great flexibility of Lisp. It is now quite different from what it was, and it can become new things. The next big catastrophe in progamming languages after object-orientation will be parallelism. We shall see... Robert A. MacLachlan (ram@cs.cmu.edu)
kers@hplb.hpl.hp.com (Chris Dollin) (02/19/91)
Steve Knight said: > [3] equality doesn't work the way it does in other lisps & is >a nasty source of problems (e.g. portability) and got various responses on the lines "but how would the system know to do any better?". Surely the answer is "it doesn't; but the programmer does, and they can tell the system what to do"; viz, attatch to datatypes a user-definable equality procedure with a suitable default (probably structural equality). Thus a defstruct would have a equality-predicate option (eqp?) and all the system types would come equipped with standard-defined eqp's (which might be indirected through symbols, so they could be changed if one felt reckless). The standard function eqp could then just dispatch through a type-indexed table. The only question that comes to mind is whether the indexing should be on one argument or two, and if on one, whether we assume that two objects of different data-type can ever be equal - sorry eqp - eg is (eqp 1.0 1) true or not? -- Regards, Kers. | "You're better off not dreaming of the things to come; Caravan: | Dreams are always ending far too soon."
barmar@think.com (Barry Margolin) (02/20/91)
In article <KERS.91Feb19153205@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes: > >Steve Knight said: > > > [3] equality doesn't work the way it does in other lisps & is > >a nasty source of problems (e.g. portability) > >and got various responses on the lines "but how would the system know to do any >better?". Surely the answer is "it doesn't; but the programmer does, and they >can tell the system what to do"; viz, attatch to datatypes a user-definable >equality procedure with a suitable default (probably structural equality). > >Thus a defstruct would have a equality-predicate option (eqp?) and all the >system types would come equipped with standard-defined eqp's (which might be >indirected through symbols, so they could be changed if one felt reckless). The >standard function eqp could then just dispatch through a type-indexed table. I started writing a paper for Lisp Pointers on this subject a couple of years ago, but never got it polished enough for submission. I covered both equality and copying. My proposal used CLOS to define the generic operations. One issue I grappled with is that equality and copying are dependent on context, not just types. For instance, if you pass a pair of conses to an equality predicate, the equality algorithm depends on whether you are treating it as a tree, an association list, or a set. My solution was to allow particular types to define keyword arguments so that they can be further parametrized. It's then up to the caller of the function to realize that the data structure contains types that need such parametrization, and supply the options if necessary. For instance, the method for CONSes accepts keywords that specify a predicate for determining whether an object is a leaf node and how leaf nodes should be compared. >The only question that comes to mind is whether the indexing should be on one >argument or two, and if on one, whether we assume that two objects of different >data-type can ever be equal - sorry eqp - eg is (eqp 1.0 1) true or not? Since CLOS allows specialization on multiple arguments, I didn't constrain this, although I think I specified that the default primary method treats objects of different types as unequal. > > >-- > >Regards, Kers. | "You're better off not dreaming of the things to come; >Caravan: | Dreams are always ending far too soon." -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
jeff@aiai.ed.ac.uk (Jeff Dalton) (02/21/91)
In article <KERS.91Feb19153205@cdollin.hpl.hp.com> kers@hplb.hpl.hp.com (Chris Dollin) writes: > >Steve Knight said: > > > [3] equality doesn't work the way it does in other lisps & is > >a nasty source of problems (e.g. portability) > >and got various responses on the lines "but how would the system know >to do any better?". What I was, and still am, wondering is how it "doesn't work the way it does in other Lisps" and why it's a "nasty source of problems (eg, portability)". Especially since EQL works reasonably for numbers, unlike EQ in most Lisps. (EQ doesn't work "reasonably" for numbers in CL either, but CL has EQL while most other Lisps did not.) You've answered a different question, namely "How is equality handled better in Pop than in Lisp?" (I agree, by the way, that Pop handles equality in a good way and that Common Lisp would be better if it had an extendable equality predicate that could be specialized by type.) >Surely the answer is "it doesn't; but the programmer does, and they >can tell the system what to do"; But the programmer _can_ tell the system what to do, by writing a function and calling it, by writing a generic function and lots of methods, etc. > viz, attatch to datatypes a user-definable >equality procedure with a suitable default (probably structural equality). OK, here's something fairly close: (defgeneric nice-equality (x y) (:method ((r string) (s string)) (string= r s)) ;case-sensitive (:method (x y) (equalp x y))) This is, of course, another case where CL would probably have been a better language if an object system had been included from the start. -- jd