From: Pascal J. Bourguignon on
Pascal Costanza <pc(a)p-cos.net> writes:

> On 13/06/2010 12:23, Giovanni Gigante wrote:
>>
>>> Programming languages are all small, on the same order of magnitude.
>>
>>
>> Well, yes, if one takes a look at the whole java for example, suddenly
>> CL appears of subatomic size.
>> But I still think that the idea I was reporting has some truth, in the
>> sense that, apparently, CL was never designed with the "small and
>> elegant" mindset (while scheme appears to be).
>> Am I wrong?
>
> The original goals for creating Common Lisp are listed here:
> http://www.cs.cmu.edu/afs/cs.cmu.edu/project/ai-repository/ai/html/cltl/clm/node6.html#SECTION00510000000000000000

I think it's well worth quoting it in whole here, since it should
resolve a lot of "philosophical" question we often get on cll about
CL.


------------------------------------------------------------------------
1.1. Purpose

Common Lisp is intended to meet these goals:

Commonality

Common Lisp originated in an attempt to focus the work of several
implementation groups, each of which was constructing successor
implementations of MacLisp for different computers. These
implementations had begun to diverge because of the differences in
the implementation environments: microcoded personal computers
(Zetalisp, Spice Lisp), commercial timeshared computers (NIL-the
``New Implementation of Lisp''), and supercomputers (S-1
Lisp). While the differences among the several implementation
environments of necessity will continue to force certain
incompatibilities among the implementations, Common Lisp serves as
a common dialect to which each implementation makes any necessary
extensions.

Portability

Common Lisp intentionally excludes features that cannot be
implemented easily on a broad class of machines. On the one hand,
features that are difficult or expensive to implement on hardware
without special microcode are avoided or provided in a more
abstract and efficiently implementable form. (Examples of this are
the invisible forwarding pointers and locatives of Zetalisp. Some
of the problems that they solve are addressed in different ways in
Common Lisp.) On the other hand, features that are useful only on
certain ``ordinary'' or ``commercial'' processors are avoided or
made optional. (An example of this is the type declaration
facility, which is useful in some implementations and completely
ignored in others. Type declarations are completely optional and
for correct programs affect only efficiency, not semantics.)
Common Lisp is designed to make it easy to write programs that
depend as little as possible on machine-specific characteristics,
such as word length, while allowing some variety of implementation
techniques.

Consistency

Most Lisp implementations are internally inconsistent in that by
default the interpreter and compiler may assign different
semantics to correct programs. This semantic difference stems
primarily from the fact that the interpreter assumes all variables
to be dynamically scoped, whereas the compiler assumes all
variables to be local unless explicitly directed otherwise. This
difference has been the usual practice in Lisp for the sake of
convenience and efficiency but can lead to very subtle bugs. The
definition of Common Lisp avoids such anomalies by explicitly
requiring the interpreter and compiler to impose identical
semantics on correct programs so far as possible.

Expressiveness

Common Lisp culls what experience has shown to be the most useful
and understandable constructs from not only MacLisp but also
Interlisp, other Lisp dialects, and other programming
languages. Constructs judged to be awkward or less useful have
been excluded. (An example is the store construct of MacLisp.)

Compatibility

Unless there is a good reason to the contrary, Common Lisp strives
to be compatible with Lisp Machine Lisp, MacLisp, and Interlisp,
roughly in that order.

Efficiency

Common Lisp has a number of features designed to facilitate the
production of high-quality compiled code in those implementations
whose developers care to invest effort in an optimizing
compiler. One implementation of Common Lisp, namely S-1 Lisp,
already has a compiler that produces code for numerical
computations that is competitive in execution speed to that
produced by a Fortran compiler. The S-1 Lisp compiler extends
the work done in MacLisp to produce extremely efficient numerical
code.

Power

Common Lisp is a descendant of MacLisp, which has traditionally
placed emphasis on providing system-building tools. Such tools may
in turn be used to build the user-level packages such as Interlisp
provides; these packages are not, however, part of the Common Lisp
core specification. It is expected such packages will be built on
top of the Common Lisp core.

Stability

It is intended that Common Lisp will change only slowly and with
due deliberation. The various dialects that are supersets of
Common Lisp may serve as laboratories within which to test
language extensions, but such extensions will be added to Common
Lisp only after careful examination and experimentation.

The goals of Common Lisp are thus very close to those of Standard Lisp
and Portable Standard Lisp. Common Lisp differs from Standard Lisp
primarily in incorporating more features, including a richer and more
complicated set of data types and more complex control structures.

This book is intended to be a language specification rather than an
implementation specification (although implementation notes are
scattered throughout the text). It defines a set of standard language
concepts and constructs that may be used for communication of data
structures and algorithms in the Common Lisp dialect. This set of
concepts and constructs is sometimes referred to as the ``core Common
Lisp language'' because it contains conceptually necessary or
important features. It is not necessarily implementationally
minimal. While many features could be defined in terms of others by
writing Lisp code, and indeed may be implemented that way, it was felt
that these features should be conceptually primitive so that there
might be agreement among all users as to their usage. (For example,
bignums and rational numbers could be implemented as Lisp code given
operations on fixnums. However, it is important to the conceptual
integrity of the language that they be regarded by the user as
primitive, and they are useful enough to warrant a standard
definition.)

For the most part, this book defines a programming language, not a
programming environment. A few interfaces are defined for invoking
such standard programming tools as a compiler, an editor, a program
trace facility, and a debugger, but very little is said about their
nature or operation. It is expected that one or more extensive
programming environments will be built using Common Lisp as a
foundation, and will be documented separately.

There are now many implementations of Common Lisp, some programmed by
research groups in universities and some by companies that sell them
commercially, and a number of useful programming environments have
indeed grown up around these implementations. What is more, all the
goals stated above have been achieved, most notably that of
portability. Moving large bodies of Lisp code from one computer to
another is now routine.
------------------------------------------------------------------------



--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Pascal J. Bourguignon on
-BMC- <BConnoy(a)morrisonhershfield.com> writes:

>> The most commonly used dialects are Scheme and Common Lisp (and,
>> depending on your perspective, Emacs Lisp)
>
> Pascal, your contributions here (and elsewhere) are always
> appreciated. Have you any comments about the viability of ISLisp?

There are less implementations (but more than one), and less users
(but more than one), but it's an International standard instead of
just an American one. And it's close enough to CL, you could probably
write an implementation of ISLisp in CL in a week end if you ever
found an ISLisp program to run.

Technically, ISLisp is perfectly viable.

Pedagogically, since it's "smaller" than CL, and perhaps somewhat more
orthogonal, it may have its points.

--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Pascal J. Bourguignon on
Dan Weinreb <dlw(a)alum.mit.edu> writes:

> I have no idea what he means by "political correctness" when applied
> to Common Lisp. It lets you get your hands on everything just as much
> as any early Lisp.

Let's try it.


[1]> (defvar *old-read* (function cl:read))
*OLD-READ*
[2]> (defun read (&optional input-stream (eof-error-p t) (eof-value nil) (recursive-p nil))
(let ((object (funcall *old-read* input-stream eof-error-p eof-value recursive-p)))
(print `(got ,object) *trace-output*)
object))

** - Continuable Error
DEFUN/DEFMACRO(READ): #<PACKAGE COMMON-LISP> is locked
If you continue (by typing 'continue'): Ignore the lock and proceed
The following restarts are also available:
ABORT :R1 Abort main loop
Break 1 [3]> continue
WARNING: DEFUN/DEFMACRO: redefining function READ in top-level, was defined in
C
READ

;; So far so good, this implementation let us redefine READ.
;; But this is of no use:

[4]> (with-open-file (src "/tmp/test.lisp" :direction :output :if-does-not-exist :create :if-exists :supersede)
(print `(defvar *test* '(a b c)) src)
(print `(print (length *test*)) src))
(PRINT (LENGTH *TEST*))
[5]> (load "/tmp/test.lisp")
;; Loading file /tmp/test.lisp ...
3
;; Loaded file /tmp/test.lisp
T
[6]> (read-from-string "(a b c)")
(A B C) ;
7
[7]>


;; Since neither LOAD nor READ-FROM-STRING (amongst many other) will
;; use our definition. This is because implementations are allowed to
;; open-code or inline any CL function.


;; However, you can indeed override functions in CL so that other CL
;; level code will use them:

[9]> (with-input-from-string (in "(a b c)")
(read in))

(GOT (A B C))
(A B C)
[10]>

;; So that you could override READ, but you would have to override
;; also all the CL functions that call it. Which soon enough makes
;; you rewrite the whole CL implementation. What is worse than
;; Greenspunning in Lisp?

;; (Well, IMO Greenspunning in Lisp is not so bad actually, there's a whole
;; chapter about it in SICP :-) )

--
__Pascal Bourguignon__ http://www.informatimago.com/
From: Tim Bradshaw on
On 2010-06-14 19:34:32 +0100, Pascal J. Bourguignon said:

> ;; So that you could override READ, but you would have to override
> ;; also all the CL functions that call it. Which soon enough makes
> ;; you rewrite the whole CL implementation. What is worse than
> ;; Greenspunning in Lisp?

Don't redefine READ then. Instead make a readtable in which everything
invokes your own reader.

From: Pascal J. Bourguignon on
Tim Bradshaw <tfb(a)tfeb.org> writes:

> On 2010-06-14 19:34:32 +0100, Pascal J. Bourguignon said:
>
>> ;; So that you could override READ, but you would have to override
>> ;; also all the CL functions that call it. Which soon enough makes
>> ;; you rewrite the whole CL implementation. What is worse than
>> ;; Greenspunning in Lisp?
>
> Don't redefine READ then. Instead make a readtable in which
> everything invokes your own reader.

Perhaps this wouldn't works so well when loading files that
do (setf *read-table* *mine*)...

In any case, READ vs. LOAD was just an example.
We could take * vs. EXPT, or RPLACA vs. (SETF CAR), etc.

Sure whether EXPT uses * or (SETF CAR) uses RPLACA is an
implementation detail, so you shouldn't count on it anyway.

But when you're modifing the implementation, you're expected to know
these implementation details anyways, and to do implementation
specific stuff, since basically, you're changing it.


In any case, this is not a 'feature' of the language, but a feature of
the implementations. But you can always modify the source of the
implementation, just choose one that is written in Lisp ;-)

--
__Pascal Bourguignon__ http://www.informatimago.com/