> Perhaps all languages have their zealots. Lisp certainly has a few.
> I am trying to figure out why Lisp has a cult like following without
> making it into the "mainstream" as a computer language. That is, Lisp
> doesn't seem, from my parochial point of view, to have the market
> penetration of C/C++, VB (yuck!), or even the controversial Java
> language.
There are lots of people that can give a good answer to this, and in fact
have. Try searching through DejaNews. You will probably find extensive
discussions of lisp vs the rest of the world.
There is also a great essay you ought to read through to understand the
nature of lisp (and some history) a little better.
http://cbl.leeds.ac.uk/nikos/tex2html/examples/good-bad-win/good-bad-win.html
Another good site to obtain materials for lisp is
http://www.elwoodcorp.com/alu/
Finally, Paradigms of AI Programming contains an example of a partial
scheme interpreter in lisp. It might prove to be a useful starting
point. You can find out more about PAIP from
> I am hoping that some of the Lisp devotees here can explain to me why
> Lisp is such a great language and why the rest of the world hasn't
> caught on to it yet, after thirty or forty years of existence.
It did, and it let go. Read the essay to get a sense for why. I forgot to
mention Richard Gabriel's book, something like Patters of Software Design,
which has a lot more about his personal experience with Lucid, one of the
first common lisp vendors. It tells a whole lot about what happened to
lisp.
> Why would an outsider such as my self be interested? I am not a
> troll. I am seriously considering using Lisp. I have Paul Graham's
> "ANSI Common Lisp" book, and one from Guy Steele. As an exercise, I
> am planning to implement a Lisp interpreter. If I can wrap my brain
> around Lisp and find out what is so great about it, I would like to
> embed it in another application as a control and extension language,
> not unlike Emacs's usage. My project, however, is much smaller than
> Emacs. I also don't expect to be able to implement the entire ANSI
> standard, let alone CLOS. That is unless the interpreter doesn't have
> to provide to much primitive functionality and the rest can be
> implemented in Lisp itself.
>
> For the record, I am from a C++ background. C++ is the language I am
> most comfortable using, and I can think in it reasonably well. Lisp
> is quite different. I understand the syntax, but that doesn't mean I
> can write poetry or appreciate it.
>
> With luck, I will grock this thing soon. It will give me a new way to
> think which is always a good thing.
It most certainly is a new way to think. Not that I would compare *any*
experienced programmers with the undergraduates I have to TA for, but the
general tendency is to think in C/C++ and translate to lisp, once you give
them the chance to. Lisp is indeed significantly different, and I doubt you
would gain a real appreciation for it unless you have worked with it for a
somewhat extended period.
Good luck!
Sunil
I am hoping that some of the Lisp devotees here can explain to me why
Lisp is such a great language and why the rest of the world hasn't
caught on to it yet, after thirty or forty years of existence.
Why would an outsider such as my self be interested? I am not a
troll. I am seriously considering using Lisp. I have Paul Graham's
"ANSI Common Lisp" book, and one from Guy Steele. As an exercise, I
am planning to implement a Lisp interpreter. If I can wrap my brain
around Lisp and find out what is so great about it, I would like to
embed it in another application as a control and extension language,
not unlike Emacs's usage. My project, however, is much smaller than
Emacs. I also don't expect to be able to implement the entire ANSI
standard, let alone CLOS. That is unless the interpreter doesn't have
to provide to much primitive functionality and the rest can be
implemented in Lisp itself.
For the record, I am from a C++ background. C++ is the language I am
most comfortable using, and I can think in it reasonably well. Lisp
is quite different. I understand the syntax, but that doesn't mean I
can write poetry or appreciate it.
With luck, I will grock this thing soon. It will give me a new way to
think which is always a good thing.
--
David Steuber
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.
If you can't trust an anonymous person on the Internet, who can you trust?
>tras...@david-steuber.com (David Steuber "The Interloper") writes:
[snip]
>> I am hoping that some of the Lisp devotees here can explain to me why
>> Lisp is such a great language and why the rest of the world hasn't
>> caught on to it yet, after thirty or forty years of existence.
>
>It did, and it let go. Read the essay to get a sense for why. I forgot to
>mention Richard Gabriel's book, something like Patters of Software Design,
>which has a lot more about his personal experience with Lucid, one of the
>first common lisp vendors. It tells a whole lot about what happened to
>lisp.
"Patterns of Software", Richard Gabriel, Oxford University Press, 1996,
ISBN 0-19-510269-X
[snip]
--
David B. Lamkins <http://www.teleport.com/~dlamkins/>
> I am trying to figure out why Lisp has a cult like following without
> making it into the "mainstream" as a computer language. That is, Lisp
> doesn't seem, from my parochial point of view, to have the market
> penetration of C/C++, VB (yuck!), or even the controversial Java
> language.
For the purposes of this message, I'll accept your branding of Lisp
as cult even though I don't agree 100%. While a cult movie might
serve only a certain audience, Lisp is Turing powerful and highly
expressive and would suffice fine for any programmer unable to find
one of those other languages. You might similarly ask what's so
great about the Macintosh if PC's are beating them everywhere, but
the answer isn't found in a technical analysis of the PC's design,
for the most part. VHS beat out Beta Max in video tape format, too,
in spite of many saying Beta was a superior technology. What wins
the amrket wars in the marketplace is not always technical superiority.
But ok, "cult" you say and let's go with that.
Cult is about serving a need that is not served by the mainstream.
Exactly because of the prevalance of C/C++, etc. people are driven to
Lisp all the more strongly. Not all, but those who are cling
strongly. And not to the language, I think, but to the ideas. The
greater Lisp community sometimes uses other languages, but I think
never really forgets its roots. Lisp was born of the AI research
culture supporting specific features it needed particularly. Slowly
some of its features are adopted into other languages, and that's good.
But I think if you want one central reason Lisp is still not "killed"
yet it's that the other languages still don't have it right and,
sometimes "like it or not", people come back to Lisp to take refuge
in a certain kind of sanity. Cult sanity, if you insist. But
sanity nevertheless.
Features like dynamic redefinition--the obvious and yet startlingly
uncopied idea that static languages seem to hold at bay--which is that
it's useful in mid-application to be able to change a data structure
definition and still run the same image, the same code, without
restarting. Features like GC which make painstaking headway into
other languages but are still clumsy by comparison. Features like
multiple inheritance which aren't absolutely needed for simple
applications and so tend to cause people to simplistically say they
can be done without, but which are a safe haven for people who are
building applications big and complex enough that they can't be easily
shoehorned into a single-inheritance system. Features like
unwind-protect which in spite of their incredible simplicity and
elegance are missing in other languages. Features like making
integers be really integers (arbitrary precision) if they want them.
Features like optional, not required, type declarations so that
programs can be production fast if they need to be, but in prototyping
you don't have to waste time declaring things that may never be used
in production. Features like a program-callable compiler so that code
can be not only generated on the fly but compiled and used in the same
environment without loss of efficiency. On and on. Lisp is full of
features still not adopted by other languages.
And then some fortuitous accidents of chance that are often, I think,
misunderstood, but are no less powerful for the doing: The famous
"program is data" thing is an example. Many languages can represent
themselves. BASIC could represent itself with an array of strings.
But what Lisp does that is critically important in power is to choose
a representation--maybe not even the best representation--but one that
is standard. The willingness to decide not to fight over program
representation and simply to define it simply and understandably means
a whole army of automatic programming and program manipulation tools
(not the least of which is Lisp's rich macro packages and its long
tradition of research in compiler design) have grown up simply because
everyone understands and shares a common interchange format for
programs in a structured form that requires no special and parsing and
no weird ad-hoc quotation rules. It's not enough for another language
to tell you you CAN define a program representation; before they match
Lisp, they must do it and do it once and for all. Most other
languages, trying to be "small", insist on optional add-on libraries
and then have endless disputes over whose add-on library is the one
and only official standard one. This is pain for programmers because
they have to know whose C they are using. C claims to be portable
because it is ubiquitous, but Lisp (by which I mean Common Lisp
particularly) was designed to be and I think truly is way more
portable than C will ever dream of being. In the modern world where
the PC dominates, one may think portable is less and less important,
but portable is REALLY about not making dependencies on the environment,
or about capturing those dependencies in an abstract way. So CL code
speaks to the future not just to other machines. If I have an integer
of a certain range, I can declare it (INTEGER 37 416) meaning
"integer in the range 37-416, inclusive". How that is optimized
may depend on the machine. But I do not have to say "the size of
a machine word" and just hope to win. That's only one tiny example.
Pathnames, too, are structured objects that have been designed so
that the same portable conception can work on Unix, PC, MAC, VMS,
Linux, CDC 7600, Lisp Machines, ISO 9000 file system, etc.
> I am hoping that some of the Lisp devotees here can explain to me why
> Lisp is such a great language and why the rest of the world hasn't
> caught on to it yet, after thirty or forty years of existence.
Lisp has on and off been more popular than it is now. I don't see
popularity as its only measure of success. Some amount of market is
needed to keep Lisp alive and growing, and we're always happy for more
than the baseline minimum but the practical fact is that just about
any language can suffice for the low-end, and what Lisp excels at is
the harder problems. As you yourself note, VB is very popular but no
one speaks kindly of it. I wouldn't trade Lisp's place for VB's--I'm
proud of where Lisp is. Lisp tends to attract people with problems
that they've given up ever solving in other languages. At Symbolics,
where I used to work before I came to Harlequin, there was a sign on
the wall (half in jest, but there was some truth to it) saying "At
Symbolics we make hard problems easy -- and vice versa". Maybe that's
the trade, I don't know. I think it's a fundamental fact about the
universe that a single solution can't be good for every possible
situation. But that Lisp is the thing that does the hard problems
is enough. Consider that there are probably more ten dollar pocket
cameras in the world than fancy theatrical movie cameras, but it's
not a failure for the theatrical movie guys that they make what
they do.
One reason Lisp solves the hard problems is that initial workout
the AI community gave it. It required a lot of memory and disk
in those days and it was expensive compared to other alternatives.
So people turned to other things. But memory and disk get
cheaper, other alternatives get bigger, and meanwhile Lisp has held
the line on size so that it is becoming respectable again just by
waiting for others to catch up in "apparent bloat"--only Lisp still
has power packed into that size, and many other tools have grown
without offering all the power that Lisp has, so don't be surprised
if Lisp has more life in it in the future. I think the possibilities
are really just opening up for Lisp, frankly. It's a bit of a chicken
and egg problem because it needs market belief to do that, but
I think it can and should be done.
> Why would an outsider such as my self be interested? I am not a
> troll. I am seriously considering using Lisp. I have Paul Graham's
> "ANSI Common Lisp" book, and one from Guy Steele. As an exercise, I
> am planning to implement a Lisp interpreter.
Sounds like a good start. Might wanna download a copy of the
Common Lisp HyperSpec(TM). See
http://www.harlequin.com/education/books/HyperSpec/
for (free) download info and
http://www.harlequin.com/education/books/HyperSpec/FrontMatter/
to browse it online at Harlequin.
See also my articles
http://world.std.com/~pitman/PS/Hindsight.html
where I discuss the benefits of Lisp in rapid prototyping and
http://world.std.com/~pitman/PS/Lambda.html
where I discuss the choice of language as a political rather than
technical issue. (The remarks about status of certain standards are
now somewhat dated, but the general thrust of the piece is still
sound, I think.)
> If I can wrap my brain
> around Lisp and find out what is so great about it, I would like to
> embed it in another application as a control and extension language,
> not unlike Emacs's usage. My project, however, is much smaller than
> Emacs. I also don't expect to be able to implement the entire ANSI
> standard, let alone CLOS. That is unless the interpreter doesn't have
> to provide to much primitive functionality and the rest can be
> implemented in Lisp itself.
Nothing wrong with subsets. And yes, by all accounts you're best
using as small a kernel as you can and writing the rest in Lisp.
> For the record, I am from a C++ background. C++ is the language I am
> most comfortable using, and I can think in it reasonably well. Lisp
> is quite different. I understand the syntax, but that doesn't mean I
> can write poetry or appreciate it.
Just being willing to try is a good start. If you have trouble
figuring out how to think about something naturally, this is a good
forum to discuss that. I think you'll find people quite helpful,
and we're always interested to hear honest accounts of people's
experiences.
> With luck, I will grock this thing soon. It will give me a new way to
> think which is always a good thing.
I saw a talk by Gerry Susman in which he suggested that indeed the most key
contribution of computer science to the 20th century is not computation but
the terminology for describing process. That is, the ability to talk about
algorithms. That it stretches the mind, he said, and gives us ways to talk
about how that has happened rather than just repeating things over and over
until other people can parrot our actions is truly important. So I agree
with your goal and wish you luck.
--Kent
p.s. My recollection from the 1970's when the word seemed popular was that
"grok" has no "c" in it. I could be wrong, and went to check, but
(alas) it's not in my dictionary under either spelling. Anyone
got a pointer to an authority on this? It IS just the right
word, and it's a shame it's not better accepted in the language.
>Perhaps all languages have their zealots. Lisp certainly has a few.
>I am trying to figure out why Lisp has a cult like following without
>making it into the "mainstream" as a computer language. That is, Lisp
>doesn't seem, from my parochial point of view, to have the market
>penetration of C/C++, VB (yuck!), or even the controversial Java
>language.
>
>I am hoping that some of the Lisp devotees here can explain to me why
>Lisp is such a great language and why the rest of the world hasn't
>caught on to it yet, after thirty or forty years of existence.
>
I'll second Sunil's suggestion to read comp.lang.lisp on DejaNews. There
have been a lot of discussions of this nature in the past. I personally
have nothing new to add, being a relative newbie to Lisp (I got interested
in the mid-80s, after having been underwhelmed by my first exposure -- in
a college programming language survey course, of course -- in the
mid-70s). FWIW, I'd prefer not to see yet another resurrection of the
perennial "why hasn't Lisp supplanted <insert your favorite language
here>?" thread...
>Why would an outsider such as my self be interested? I am not a
>troll. I am seriously considering using Lisp. I have Paul Graham's
>"ANSI Common Lisp" book, and one from Guy Steele. As an exercise, I
>am planning to implement a Lisp interpreter. If I can wrap my brain
>around Lisp and find out what is so great about it, I would like to
>embed it in another application as a control and extension language,
>not unlike Emacs's usage. My project, however, is much smaller than
>Emacs. I also don't expect to be able to implement the entire ANSI
>standard, let alone CLOS. That is unless the interpreter doesn't have
>to provide to much primitive functionality and the rest can be
>implemented in Lisp itself.
Those are both good books. Graham's is a concise but thorough
introduction. Steele's is a reasonable reference, but you should see the
HyperSpec <http://www.harlequin.com/books/HyperSpec/> for the definitive
reference to ANSI CL. I'd also recommend Wilensky's "Common LISPcraft",
which offers more explanation, in general, than Graham's book; it is
closer to being a beginner's book, but without the patronizing
simplifications found in so many beginner's texts.
If you want to build an interpreter for the intellectual exercise, that's
great. However, if your ultimate goal is to introduce a Lisp-ish
extension language into another project, I'd suggest that you first take a
look at freely-available source for such interpreters; you'll even find
some reasonably good compilers for both Scheme and CL.
The best modern reference for Lisp implementation, IMO, is "Lisp in Small
Pieces" by Christian Quiennec (Cambridge University Press, 1996, ISBN
0-521-56247-3). This covers interpreters and compilers. It has a Scheme
orientation, but makes appropriate and informative digressions to include
techniques appropriate to CL as needed.
Be aware that a lot of your implementation effort will go into runtime
support. One of the most difficult areas of runtime and implementation
tradeoffs involves garbage collection. There is one excellent text on
this subject: "Garbage Collection" by Jones and Lins (Wiley, 1996, ISBN
0-471-94148-4).
AFAIK, Lisp is one of the few languages that, in a typical implementation,
allows implementation of "precise" garbage collection. This is so because
there are typically a small number of well-know pointers (in the
underlying implementation, not available to the Lisp programmer) from
which all other accessible storage can be reached. This allows the GC to
reclaim "precisely" everything that is unused by the running program. The
alternative "conservative" approach uses hueristics to decide which
storage is still live; the hueristics must guess "conservatively" to keep
live storage from being reclaimed -- typically these GCs overestimate by a
small percentage.
>
>For the record, I am from a C++ background. C++ is the language I am
>most comfortable using, and I can think in it reasonably well. Lisp
>is quite different. I understand the syntax, but that doesn't mean I
>can write poetry or appreciate it.
>
>With luck, I will grock this thing soon. It will give me a new way to
>think which is always a good thing.
I believe that Samuel Kamin (?) has published a book (sorry, no reference
available) of interpreters implemented in C++. I'm pretty sure that there
is a Lisp among them.
One thing I think you'll find as you learn to think and program in Lisp is
that it provides a remarkable economy of expression, which will help you
to solve real problems in less time. (Disclaimer: If you have a problem
that's solved by simple, repetitive load-operate-store sequences, then
you'll probably solve it more concisely in C or FORTRAN. But systems
programs -- to which Lisp is well-suited -- are generally not as tidy as
benchmarks, image processing, and numerical programs.) Having been
through the exercise quite a few times, I'm _still_ pleasantly surprised
when a Common Lisp program is a fraction (typically 1/5 or smaller) of the
size of an equivalent C/C++ program.
:grok: /grok/, var. /grohk/ /vt./ [from the novel
"Stranger in a Strange Land", by Robert A. Heinlein, where it
is a Martian word meaning literally `to drink' and metaphorically
`to be one with'] The emphatic form is `grok in
fullness'. 1. To understand, usually in a global sense. Connotes
intimate and exhaustive knowledge. Contrast {zen}, which is
similar supernal understanding experienced as a single brief flash.
See also {glark}. 2. Used of programs, may connote merely
sufficient understanding. "Almost all C compilers grok the
`void' type these days."
[JARGON 4.0.0]
Hope i could help :)
-forcer
--
;; Build a system that even a fool can use and only a fool will use it.
;; email: for...@mindless.com -><- www: http://webserver.de/forcer/
;; IRC: forcer@#StarWars (IRCnet) -><- PGP/GPG: available on my website
<snip>
> As an exercise, I am planning to implement a Lisp interpreter.
I assume you mean to implement one in C or C++, in which case, don't
do that. You'll end up with an understanding of how a Lisp
interpreter works & how to implement one in C or C++, but you won't
end up with an understanding of programming in Lisp.
To understand Lisp, you should program in it. As you repeatedly
become amazed at how easy & simple it is to do things that'd be hard &
complex in C or C++ then you'll start understanding why Lisp has its
following. When you start doing meta-programming in Lisp then
you'll start to really understand it.
Most lisp books are pretty decent, and others have recommended some.
But, I'd recommend Structure and Interpretation of Computer Programs
by Abelson and Sussman. It's scheme & not common lisp, but it does a
good job of illustrating a variety of lisp programming paradigms.
--
Harvey J. Stein
BFM Financial Research
hjs...@bfr.co.il
>> If I can wrap my brain
>> around Lisp and find out what is so great about it, I would like to
>> embed it in another application as a control and extension language,
>> not unlike Emacs's usage. My project, however, is much smaller than
>> Emacs. I also don't expect to be able to implement the entire ANSI
>> standard, let alone CLOS. That is unless the interpreter doesn't have
>> to provide to much primitive functionality and the rest can be
>> implemented in Lisp itself.
>
>Nothing wrong with subsets. And yes, by all accounts you're best
>using as small a kernel as you can and writing the rest in Lisp.
>
You may also wish to look at Guile, the GNU extension language. It is
an implementation of Scheme built for the kind of problem you are
discussing.
Common Lisp would be nice, but it may not be worth the overhead in a
small application.
--
Kenneth P. Turvey <ktu...@pug1.SprocketShop.com>
An atheist is a man with no invisible means of support.
-- John Buchan
>p.s. My recollection from the 1970's when the word seemed popular was that
> "grok" has no "c" in it. I could be wrong, and went to check, but
> (alas) it's not in my dictionary under either spelling...
American Heritage (electronic) Dictionary v.4 says:
grok (grÄk) v. tr. grok€ked grok€king groks
Slang 1. To understand profoundly through intuition or empathy.
[ Coined by Robert A. Heinlein in his Stranger in a Strange Land]
(I don't know whether AHD is on-line.)
An on-line meta-dictionary is at http://www.onelook.com/
Merriam-Webster is at http://www.m-w.com/cgi-bin/dictionary
(which does not contain the word grok)
----
Many have explained why lisp isn't in mainstream. A self-serving meta-answer
is that that is the result of theory of economy. (basically, it just means
that lisp failed to become mainstream by social forces) One significant
reason is that supreme ideas takes time for the average to realize. Or,
cynically: "people are stupid". In an ideal word, suppose every programer
has deep interest and knowledge in computer science, mathematics, and
philosophy, then it is likely that lisp ideas will be the mainstream. In the
real word, not all programers are properly trained, and of the many degree
holders (a dime a dozen these days), lots are unthinking products of mass
education, whose interests in sciences are mostly career based.
It is worth noting that it is a fact that lisp is not in mainstream, and
this is so because of people. (your Providence does not play favoritism on
ideas good or bad.)
The section "the rise of worse-is-better" of Richard Gabriel's essay at
http://cbl.leeds.ac.uk/nikos/tex2html/examples/good-bad-win/node9.html
explains some aspects of why lisp's good ideas may be less popular. A more
detailed
analysis along the same idea is the article "Big Ball of Mud" at
http://www-cat.ncsa.uiuc.edu/~yoder/papers/patterns/BBOM/mud.html
This long article analyze the survival characteristics of codes we normally
call hacking (big ball of mud), and in general condone such practices. This
article fails to indicate a significant reason (the social element) in why
"big ball of mud" are popular: Most programers are average. The Average
lacks knowledge in advanced mathematics, imposing philosophy, or rigors of
discipline. It is easy to see that the Average will sloppily code away
without giving a fart to theories, especially with respect to many of the
technical reasons cited in the article (in essence, the reward of discipline
is elusive. (especially so with regards to the infant stage of computer
science.)).
With hardware faster and faster and advances in communication (esp.
internet), I think the technical reasons that hinders lisp popularity is
decreasing, and the superiority of lisp (or lisp-like modern languages (i.e.
functional languages)) will _eventually_ become mainstream. (java is not one
of them.)
(it is a folklore that "good ideas will eventually win", but it is worth
noting that if true, the process is never automatic. Mass education takes
time and effort: Lispers cannot just sit there and expect gospels to knock
the Average head. Evangelize, fight, do something!)
Xah, x...@best.com
http://www.best.com/~xah/PageTwo_dir/more.html
Perl: all unix's stupidity in one.
1. Lisp incorporates many (all?) of the good ideas in programming, in the
areas of:
+ programming style: object-oriented, functional, etc.
+ environment: libraries, interactive/dynamic development, etc.
+ computation: control structure, memory management, lambda calculus,
etc.
etc.
2. Lisp incorporates all these ideas not in an ad-hoc way, but in a
coordinated, integrated fashion.
3. The above would be enough to make Lisp a "darn good language", but
there are others to choose
from. Each Lisp devotee has further found at least one "killer
feature" of the language which other
languages cannot compete with. (For many, myself included, this
feature is the ability to use the
full language to create program-transformation programs. This is
enabled by the combination
of macros, program-is-data, and the dynamic compilation
environment. Perhaps any lack of
market pervasiveness comes ultimately from the failure of most
programmers to find their own
"killer feature" in Lisp.)
Some of these issues are mentioned at
http://www.elwood.com/alu/table/lisp.htm, and in particular, in the essays
referenced from http://www.elwood.com/alu/table/compare.htm and other places
on the site. You may find the C++ comparisons particularly useful.
With respect to using Lisp as as an extension language. I think this is a
great idea to learn more about Lisp once you have some background, but may
not be the best way to start. I also believe that if you want something for
serious or commercial use, you might consider one of the existing systems.
See the ALU website, referenced above. Of course, I also recommend my
company's Eclipse product, which was designed for this purpose
(http://www.elwood.com/eclipse-info).
> p.s. My recollection from the 1970's when the word seemed popular was that
> "grok" has no "c" in it. I could be wrong, and went to check, but
> (alas) it's not in my dictionary under either spelling. Anyone
> got a pointer to an authority on this? It IS just the right
> word, and it's a shame it's not better accepted in the language.
Grok comes from Robert Heinlein's novel "Stranger in a Strange Land" and
it indeed has no C.
Erann Gat
g...@jpl.nasa.gov
% Grok comes from Robert Heinlein's novel "Stranger in a Strange Land" and
% it indeed has no C.
This is where my usage comes from. Unfortunately, I lack conventional
spelling skills. Sometimes words get past the spell checker.
--
David Steuber
http://www.david-steuber.com
To reply by e-mail, replace trashcan with david.
When the long night comes, return to the end of the beginning.
--- Kosh (???? - 2261 AD) Babylon-5
% tras...@david-steuber.com (David Steuber "The Interloper") writes:
%
% > I am trying to figure out why Lisp has a cult like following without
% > making it into the "mainstream" as a computer language.
%
% For the purposes of this message, I'll accept your branding of Lisp
% as cult even though I don't agree 100%.
I hope I didn't bring offense with the word cult. I meant it in the
sense of a small, enthusiastic following, not the religious sense.
Minority opinions are not always wrong. Heck, I wouldn't be surprised
if the minority views on most any issue were better thought out.
% Cult is about serving a need that is not served by the mainstream.
% Exactly because of the prevalance of C/C++, etc. people are driven to
% Lisp all the more strongly. Not all, but those who are cling
% strongly. And not to the language, I think, but to the ideas. The
% greater Lisp community sometimes uses other languages, but I think
% never really forgets its roots. Lisp was born of the AI research
% culture supporting specific features it needed particularly.
The AI connection is what attracts me to the language. Also the
simplicity of the syntax for parsing and evaluating purposes. My
interest is to implement an interpreter of Lisp in Java, leveraging
Java's garbage collection. I would hate to write my own garbage
collector with my meager talents. Also, Lisp appears to be a language
that would be exceptionally good for describing complex data
structures. That is, I could leverage the Lisp interpreter by making
Lisp my file format. Additional possibilities are also in my mind.
It may be useful to attach Lisp functions (or objects, I haven't seen
CLOS yet) to my data objects as properties. I haven't got a fully
formed design in my mind yet, but Lisp should be able to completely
describe a model and its behavior. This I may be able to do in Java
(it's like a third language to me), but I have an inkling that Lisp
may do the job better and in a more portable fashion.
% And then some fortuitous accidents of chance that are often, I think,
% misunderstood, but are no less powerful for the doing: The famous
% "program is data" thing is an example. Many languages can represent
% themselves. BASIC could represent itself with an array of strings.
I've done this in Perl. Well, sort of. I used Perl's eval function
to evaluate dynamically loaded code. I also have dynamically created
regular expressions in Perl. But Perl is not a language I wish to use
for my project.
% But what Lisp does that is critically important in power is to choose
% a representation--maybe not even the best representation--but one that
% is standard. The willingness to decide not to fight over program
% representation and simply to define it simply and understandably means
% a whole army of automatic programming and program manipulation tools
% (not the least of which is Lisp's rich macro packages and its long
% tradition of research in compiler design) have grown up simply because
% everyone understands and shares a common interchange format for
% programs in a structured form that requires no special and parsing and
% no weird ad-hoc quotation rules. It's not enough for another language
% to tell you you CAN define a program representation; before they match
% Lisp, they must do it and do it once and for all. Most other
This is one of the features that attracts me to Lisp.
% languages, trying to be "small", insist on optional add-on libraries
% and then have endless disputes over whose add-on library is the one
% and only official standard one. This is pain for programmers because
% they have to know whose C they are using. C claims to be portable
% because it is ubiquitous, but Lisp (by which I mean Common Lisp
% particularly) was designed to be and I think truly is way more
Me too (Common Lisp).
% portable than C will ever dream of being. In the modern world where
% the PC dominates, one may think portable is less and less important,
% but portable is REALLY about not making dependencies on the environment,
% or about capturing those dependencies in an abstract way. So CL code
% speaks to the future not just to other machines. If I have an integer
% of a certain range, I can declare it (INTEGER 37 416) meaning
% "integer in the range 37-416, inclusive". How that is optimized
% may depend on the machine. But I do not have to say "the size of
% a machine word" and just hope to win. That's only one tiny example.
% Pathnames, too, are structured objects that have been designed so
% that the same portable conception can work on Unix, PC, MAC, VMS,
% Linux, CDC 7600, Lisp Machines, ISO 9000 file system, etc.
I don't get the need for an integer type in a certain range. But that
is my inexperience. However, portability is important for me. I want
people to have sufficient reason to move away from Microsoft OS.
Therefor, I don't want to target Windows specifically. At the same
time, I only want to do one build. For now, Java offers me that
capability. However, I am not certain of the success of Java. If I
can incorporate portions of my application in Lisp, there is less to
port if Java fails. The c.l.j.a group would hate me for saying that.
That brings up another point. I must say that this is about the
friendliest news group I've read. I haven't read more than about four
dozen postings. In that small sample, all the talk has been at a high
level of politeness. I'm not sure how else to put it. In any of the
other news groups I've been in, I would have read several flames.
If I was in comp.lang.java.advocacy asking the same questions about
Java's following and lack of real market success, I would have had to
wear an asbestos suit! This to me speaks very highly of the Lispers.
% Lisp has on and off been more popular than it is now. I don't see
% popularity as its only measure of success. Some amount of market is
% needed to keep Lisp alive and growing, and we're always happy for more
% than the baseline minimum but the practical fact is that just about
% any language can suffice for the low-end, and what Lisp excels at is
% the harder problems. As you yourself note, VB is very popular but no
But if Lisp was a mainstream language, it would be much easier to
distribute software written with it. Even more so if there was a
standard p-code form that it could be compiled to (like Java) so that
it could be distributed in binary form.
% one speaks kindly of it. I wouldn't trade Lisp's place for VB's--I'm
% proud of where Lisp is. Lisp tends to attract people with problems
% that they've given up ever solving in other languages. At Symbolics,
And VB, IMNSHO, is probably one of the biggest causes (if not the
biggest) of bad software. I'm all for languages that are easy to
learn. I hope Lisp falls into that category. There is just one
syntax. I just need to hear the song (Vorlon reference).
% the trade, I don't know. I think it's a fundamental fact about the
% universe that a single solution can't be good for every possible
% situation. But that Lisp is the thing that does the hard problems
% is enough. Consider that there are probably more ten dollar pocket
% cameras in the world than fancy theatrical movie cameras, but it's
% not a failure for the theatrical movie guys that they make what
% they do.
I wouldn't expect Lisp to perform well in an embedded system like the
Engine Control Unit in my car. But for general computing (even
serious number crunching), why shouldn't Lisp or some other language
be the best at everything? If you can say everything in the language,
and work with all the data types and representations, then all that is
left is to convert the human readable representation into the optimum
machine readable representation. Or am I missing something? I don't
have a CS degree, so it is entirely possible. Actually, I am a
fallible human. That is why I can't see everything.
% One reason Lisp solves the hard problems is that initial workout
% the AI community gave it. It required a lot of memory and disk
% in those days and it was expensive compared to other alternatives.
% So people turned to other things. But memory and disk get
% cheaper, other alternatives get bigger, and meanwhile Lisp has held
% the line on size so that it is becoming respectable again just by
% waiting for others to catch up in "apparent bloat"--only Lisp still
% has power packed into that size, and many other tools have grown
% without offering all the power that Lisp has, so don't be surprised
% if Lisp has more life in it in the future. I think the possibilities
% are really just opening up for Lisp, frankly. It's a bit of a chicken
% and egg problem because it needs market belief to do that, but
% I think it can and should be done.
Emacs is written in Lisp. Unfortunately, PC people don't get to play
with it except for the NT Emacs at Volker's site. I saw XEmacs on a
Sun box today. Very nice.
AutoCad has AutoLisp for doing things. I haven't messed with that
monstrosity in some years now.
It is as if Lisp is lurking around the corner, but just won't show
itself. I think you are probably right except for one thing. I have
a rule that I used to just apply to the stock market. But I have
found that it is almost universal. Never bet against stupidity. I
can't help but think how much smaller and simpler Microsoft Word would
be if it was written in Lisp with a built in interpreter so that a
user could write Lisp extensions to customize Word. I guess that
would be too much like a graphical version of Emacs! Anyway, who
would want CaptiveLisp?
% Sounds like a good start. Might wanna download a copy of the
% Common Lisp HyperSpec(TM). See
% http://www.harlequin.com/education/books/HyperSpec/
% for (free) download info and
% http://www.harlequin.com/education/books/HyperSpec/FrontMatter/
% to browse it online at Harlequin.
%
% See also my articles
% http://world.std.com/~pitman/PS/Hindsight.html
% where I discuss the benefits of Lisp in rapid prototyping and
% http://world.std.com/~pitman/PS/Lambda.html
% where I discuss the choice of language as a political rather than
% technical issue. (The remarks about status of certain standards are
% now somewhat dated, but the general thrust of the piece is still
% sound, I think.)
Thanks for the links. I'll check them out as soon as I can.
% I saw a talk by Gerry Susman in which he suggested that indeed the most key
% contribution of computer science to the 20th century is not computation but
% the terminology for describing process. That is, the ability to talk about
% algorithms. That it stretches the mind, he said, and gives us ways to talk
% about how that has happened rather than just repeating things over and over
% until other people can parrot our actions is truly important. So I agree
% with your goal and wish you luck.
I have found that verbal skills seem to be more important than math
skills in computing. Sure, math is important. But both math and
communication require abstract thinking. We think about a process in
the abstract and then try to communicate it in a way that the receiver
forms the same abstraction. A modern programming language is nothing
more than an interface between the human and the machine. It does
have to pull of a neat trick though. It has to be both machine
readable and human readable. Natural language is full of ambiguity
that just can't exist in a computer language. Also, it seems that the
computer language we think in shapes they way we approach a problem
much like the natural language we speak shapes the way we communicate
our ideas. I'm sure this could be stated better.
In the English language, the phrase "the answer, my friend, is blowing
in the wind" can be interpreted at least three different ways.
Thanks to everyone else who replied to my post, both in this news
group and by e-mail. You have bolstered my determinism to learn Lisp.
Some of you have recommended Scheme. I was considering Scheme until I
was able to find a source for the Common Lisp standard. It may be
myopic and parochial of me, but I want to deal with just one Lisp.
Even Emacs Lisp is an additional burden my finite mind doesn't wish to
cope with at this time. Then again, the Scheme spec is much smaller.
Laziness might make me reconsider.
What is it that makes an engineer? Laziness, impatience, and hubris?
Or is that why Unix and Perl are the way they are?
Well, I'll be squatting here for a while.
* g...@jpl.nasa.gov (Erann Gat)
| Grok comes from Robert Heinlein's novel "Stranger in a Strange Land" and
| it indeed has no C.
FWIW, it was included in Merriam-Webster's Ninth Collegiate Dictionary,
but had been removed in the Tenth edition.
#:Erik
--
http://www.naggum.no/spam.html is about my spam protection scheme and how
to guarantee that you reach me. in brief: if you reply to a news article
of mine, be sure to include an In-Reply-To or References header with the
message-ID of that message in it. otherwise, you need to read that page.
> * Kent M Pitman
> | p.s. My recollection from the 1970's when the word seemed popular was that
> | "grok" has no "c" in it. I could be wrong, and went to check, but
> | (alas) it's not in my dictionary under either spelling. Anyone
> | got a pointer to an authority on this? It IS just the right
> | word, and it's a shame it's not better accepted in the language.
>
> * g...@jpl.nasa.gov (Erann Gat)
> | Grok comes from Robert Heinlein's novel "Stranger in a Strange Land" and
> | it indeed has no C.
>
> FWIW, it was included in Merriam-Webster's Ninth Collegiate Dictionary,
> but had been removed in the Tenth edition.
>
> #:Erik
FTR its also in "The New Hackers Dictionary" (2nd Edition) without the "c".
According to this source the (Martian) work literally means "to drink" and
metaphorically means "to be one with".
__Jason
If you're willing to sacrifice raw speed for size (typical for some
scripting uses - mine at least) you might also want to look at
TinyScheme
at my homepage below. It's a single C module around 4000 kloc,
but near-R5RS Scheme nevertheless.
--
Dimitrios Souflis dsou...@altera.gr
Altera Ltd. http://www.altera.gr/dsouflis
*** Reality is what refuses to disappear when you stop believing
*** in it (VALIS, Philip K. Dick)
> The AI connection is what attracts me to the language. Also the
> simplicity of the syntax for parsing and evaluating purposes. My
> interest is to implement an interpreter of Lisp in Java, leveraging
> Java's garbage collection.
Check out http://www.norvig.com/SILK.html
Scheme in Fifty KB. (in Java).
You're welcome.
--
Bradford W. Miller
(I have a job, but you're talking to me)
Disclaimer: There are no states, corporations, or other pseudo-individuals.
There are only people. Justify your actions without resorting to your
orders.
"Unlike me, many of you have accepted the situation of your imprisonment
and will die here like rotten cabbages."
- Number Six's speech from "Free for All" _The Prisoner_
% Check out http://www.norvig.com/SILK.html
%
% Scheme in Fifty KB. (in Java).
%
% You're welcome.
Come up with a demented idea, and someone else has already implemented
it.
% If you're willing to sacrifice raw speed for size (typical for some
% scripting uses - mine at least) you might also want to look at
% TinyScheme
% at my homepage below. It's a single C module around 4000 kloc,
% but near-R5RS Scheme nevertheless.
Thanks. I'll take a look. I am really more interested in Common Lisp
though. Still, the scanning should be the same. As far as I know, no
one has been dumb enough to do the interpreter in Java like I want to.
Do you mean to say 4 MLOC, or 4 KLOC or what? Just wondering.
--
Greg Pfeil --- Software Engineer --- (pfeilgm@|http://)technomadic.org
"I was a victim of a series of accidents, as are we all."
--Malachi Constant in _The Sirens of Titan_
I take this to mean that you think the lexical analysis of Scheme and
Common Lisp are similar or the same. this is not so. Common Lisp has a
programmable reader that is used to read Lisp forms, while Scheme uses a
very static syntax that is even outside of Scheme itself. (i.e., Common
Lisp uses READ and uses the value of *READTABLE* even for code, while
Scheme cannot use READ because the syntax is specified as sequences of
characters, not as forms.)
I also don't think you really want an interpreter for Common Lisp. it
seems like less work to compile Common Lisp to the JVM elsewhere, and
then compile enough Common Lisp code to sustain a development enviroment
on the JVM itself. I haven't seen any reports from the several people
who have expressed interest in such a stunt over the past couple years,
but you will certainly be a hero if you do it.
Erik, I assume you're wearing some sort of "standards purist" hat while
saying this...? ;-} Yes, of course, in principle you are absolutely
correct, but in practice I don't know of a single Scheme implementation
that does *NOT* use the same lexer for the user-visible READ procedure and
the reader buried in the LOAD procedure and the top-level REPL. In fact,
now that EVAL is in R5RS, one could even make Scheme's LOAD an optional
procedure, which could be coded by the user as:
(define (load fname)
(with-input-from-file fname
(lambda ()
(do ((exp (read) (read)))
((eof-object? exp)) ; note: returns unspec. value
(eval exp (interaction-environment))))))
And, except for the lack of error-handling, this:
(let loop ()
(display "my-repl> ")
(write (eval (read) (interaction-environment)))
(newline)
(loop))
is a perfectly functional REPL in every Scheme I've ever used. [O.k.,
so you have to leave off the 2nd arg to "eval" in the older ones...]
In fact, I can't see any way to *avoid* this, since R5RS explictly says
that READ "...is a parser for the nonterminal <datum>" [6.6.2], and
also, "Note that any string that parses as an <expression> also parses
as a <datum>." [7.1.2] So it should be perfectly correct to use READ
for Scheme expressions (well-formed ones, that is).
On the other hand... There is no defined way in Scheme to extend or modify
the syntax accepted by READ. With only one or two ad-hoc exceptions (dare I
say "hacks"?), I haven't seen anything in the Scheme world that comes close
to the Common Lisp notion of *READTABLE*, and certainly nothing that works
the same way in more than one implementation. And that's quite unfortunate,
given the wide differences in lexical "extensions" supported by various
Schemes. Some allow |CaseSensitiveSymbols With Spaces InVerticalBars| and
some don't. Some allow #|multi-line comments|# and some don't. A very few
support "#."; most don't. Were there a widely-accepted readtable-equivalent,
one could gloss over these differences. But as it is, if one is trying to
write Scheme code which will be even barely portable, one must simply avoid
*everything* that's not explcitly mentioned in R5RS [or even R4RS]. (*sigh*)
Hmmmm... But on the third hand [as Niven & Pournelle say], in R5RS "READ"
is listed as a "library" procedure, which means that while conforming
implementations must provide one [it's not an "optional" library procedure]
it need not be primitive -- it can be implemented in terms of other, more
primitive features. Just start with "READ-CHAR", and parse it yourself.
(I've done that before, actually, as an exercise.) There are enough required
type-conversion routines [I'm thinking specifically of "string->symbol"
and "char->integer"] to allow building any Scheme object up out of pieces.
Maybe *that's* supposed to be "the Scheme way" to get reader extensibility...?
-Rob
-----
Rob Warnock, 8L-855 rp...@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
2011 N. Shoreline Blvd. FAX: 650-964-0811
Mountain View, CA 94043 PP-ASEL-IA
Stalin uses different code to implement READ and to read in the source program.
When the source program is read in, the reader keeps track of source file
name, line, and character positions to include in error messages. READ does
not do this. In fact, the source program reader doesn't produce a typical
S expression. Rather it produces a structure of type S-EXPRESSION which
includes the encapsulated file, line, and character position.
% * tras...@david-steuber.com (David Steuber "The Interloper")
% | I am really more interested in Common Lisp though. Still, the scanning
% | should be the same. As far as I know, no one has been dumb enough to do
% | the interpreter in Java like I want to.
%
% I take this to mean that you think the lexical analysis of Scheme and
% Common Lisp are similar or the same. this is not so. Common Lisp has a
% programmable reader that is used to read Lisp forms, while Scheme uses a
% very static syntax that is even outside of Scheme itself. (i.e., Common
% Lisp uses READ and uses the value of *READTABLE* even for code, while
% Scheme cannot use READ because the syntax is specified as sequences of
% characters, not as forms.)
Does this mean that while CL can read CL and eval it, Scheme can not
read Scheme and eval it? I am running into confusion here. I was
under the impression that Scheme was a dialect of Lisp. From what you
say, Scmeme is a whole other language (like JavaScript isn't Java).
% I also don't think you really want an interpreter for Common Lisp. it
% seems like less work to compile Common Lisp to the JVM elsewhere, and
% then compile enough Common Lisp code to sustain a development enviroment
% on the JVM itself. I haven't seen any reports from the several people
% who have expressed interest in such a stunt over the past couple years,
% but you will certainly be a hero if you do it.
I still don't know if the Java byte code is flexible enough to allow
CL to be compiled to it. Also, the JVM only accepts .class files that
have to pass the byte code verifier. I have certainly thought of
doing that. It seems the more I learn about Lisp, the more it makes
sense for a Lisp interpreter to be written in Lisp. In either case,
there would have to be support classes written in Java for presenting
a runtime for Lisp in the JVM. It also makes sense to allow the Lisp
to use the other Java APIs via the Class class and reflect package.
This figment of my imagination has been labeled jLisp and is about as
vaporware as you can get.
This brings up another question. It seems that Lisp is not case
sensitive. How many people would be upset if a Lisp implementation
came out that was case sensitive? It sure makes string comparison
easier. This is just my view from a C++ background.
> This brings up another question. It seems that Lisp is not case
> sensitive. How many people would be upset if a Lisp implementation
> came out that was case sensitive? It sure makes string comparison
> easier. This is just my view from a C++ background.
Common Lisp IS case-sensitive.
The Lisp reader, however, is case-translating.
Internally, these symbols are all indistinguishable (i.e., EQ) and
all-uppercase:
foo Foo FOO |FOO|
The following symbols are indistinguishable and are all-lowercase:
|foo| \f\o\o \f|oo|
These symbol pairs are different (i.e., not EQ):
Foo |Foo| ; the former is all-uppercase, the latter is uppercase initial
foo |foo| ; the former is all-uppercase, the latter is all-lowercase
FOO |foo| ; the former is all-uppercase, the latter is all-lowercase
Further, there is no reason to make a Lisp implementation that is
case-sensitive. It would break enormous amounts of code to do so.
The language already provides these features:
*print-case* - special variable
readtable-case - function on readtables
Look them up in the Common Lisp HyperSpec(TM) for details. They are
plenty powerful enough to obviate the need for a non-conforming Lisp.
Further: string comparison has nothing to do with symbols. It's true
that FOO and |foo| are different symbols but not because they have
different names; rather because they are different objects (implicit
pointer compare). Of course, they have different pointers because
they have different names; but that's just coincidence. One shouldn't
confuse felicity with causality. For example, #:FOO and FOO and :FOO
have the same name and that doesn't make them the same symbol.
They are different pointers because one has no package, one is
in the prevailing package, and one is in the keyword package.
Then once they have different pointers, you compare them with EQ
and string compares are irrelevant.
But if you were using strings, you can either choose to compare them
as objects (in which case "Foo" and "FOO" are different under EQ
since they can't have the same pointer if they have different
elements) or you can compare them as strings, in which case you
have to choose STRING-EQUAL (case-insensitive) or STRING=
(case-sensitive). I don't see that either is easier than the
other. They are different. And you should use the right one for
the right purpose.
A problem caused by c-insensitivity mentioned in R*RS is the string-symbol
conversion.
Guile scheme is case sensitive by default (it can be turned off optionally.).
Klaus Schilling
Yes, well, o.k., I misspoke (or perhaps wasn't specific enough). Yes, I
know of other Scheme readers (well, at least one) which annotate the source
similarly (e.g., the one in the Rice PLT group's "MrSpidey"). But what I was
referring to is that the user-visible READ *does* accept all legal source
programs, so that Erik's distinction between "prgrams defined by lexical
rules" and "programs defined by S-exprs" is, for all practical purposes, moot.
Now it is certainly the case that one could make a *mistake* in defining a
Lisp (or Scheme) by its lexical representation in such a way that there was
*not* a guarantee of equivalency, but I also suspect that most participants
in this group would consider such a definition badly broken (if only because
of the negative implications on macros).
+---------------
| READ does not do this. In fact, the source program reader doesn't produce
| a typical S expression. Rather it produces a structure of type S-EXPRESSION
| which includes the encapsulated file, line, and character position.
+---------------
Call me naive, but I don't see how this affects the issue... unless there
are files which Stalin [or some other Lisp or Scheme] will accept as programs
which its READ *won't* accept when a user program tries to read them (e.g.,
say, allowing allows "#+<sym>" or "#.<exp>" in "programs" but not in files
parsed with READ). And if there are, I'd call it broken.
-Rob
[p.s. Apologies in advance: Replies to this via email may get a
"vacation" bounce messages while I'm on sabbatical from SGI...]
You are right in wondering... It is 4 kloc, or else it would be
MegaScheme ;-)
More precicely it is 4110 loc (.c+.h), which is either 4.1 kloc
or 4.0 kloc, depending on whether you use "kilo" for "thousand"
or 2^10=1024.
well, no, it means that you need a whole different machinery to read
Common Lisp than you need to read Scheme. Scheme was designed in the
fashion of static grammars, and people frequently implement the reader in
some other language. Common Lisp's reader is best written in Common Lisp
-- it dispatches on characters according to a table, the READTABLE, and
call out to functions that assemble the various types of objects. this
is overkill per excellence for Scheme. also, Scheme's grammar is defined
so that (foo 1 2 . ()) is different from (foo 1 2), although the Scheme
reader cannot detect this difference. therefore, you will not catch very
important errors if you use the naive approach to Scheme. (no, I'm not
talking in the "standards purist" mode -- Scheme is deliberately designed
this way, and second-guessing designers is a Bad Thing. of course, it
was a gross and very annoying mistake, but the designers should fix that,
not users.)
| I was under the impression that Scheme was a dialect of Lisp. From what
| you say, Scmeme is a whole other language (like JavaScript isn't Java).
Scheme is not a dialect of Common Lisp. the common heritage, if any, is
so old and so far removed from today's reality that we're almost talking
about a missing link. Scheme owes more to Algol than to Lisp, in my
view, just like Java owes more to Smalltalk than to C++. the syntactic
similarity is irrelevant for meaningful comparisons. Scheme adherents
want to tell you Scheme is a dialect of Lisp, but I don't get it. what
do _they_ get from confusing people like that? is it a hope for a piece
of the market that Common Lisp has created? some Lispers (well, at least
one, but he's also a Schemer) will insist very strongly that Common Lisp
is not the only Lisp to consider. the only merit of this latter attitude
is that it makes the Scheme wish come true, but there aren't as many
Lisps as there used to be 10-15 years ago. if you spend your time
learning any other Lisp these days, I'd say you're wasting your time
unless, of course, the Lisp is an embedded Lisp in some product you need
to use. (this includes the sadly deficient Emacs Lisp.)
| This brings up another question. It seems that Lisp is not case
| sensitive.
well, I can't speak for "Lisp" in the sense that it is something that
Scheme is (also) a dialect of, but Common Lisp is certainly case
sensitive. symbols in the COMMON-LISP package are all uppercase, but you
would normally set *PRINT-CASE* to :DOWNCASE and (readtable-case
*readtable*) to :UPCASE, so you could read and write them in lowercase.
both |lowercase| and \l\o\w\e\r\c\a\s\e all have lowercase symbol names,
so it's not like you cannot get it. also, to maintain backward
compatibility, you can set the readtable-case to :INVERT, which upcases
all-lowercase symbol names and downcases all-uppercase symbol names (not
counting characters escaped with | or \).
| How many people would be upset if a Lisp implementation came out that was
| case sensitive?
if you make the reader preserve case, many would object to having to
write symbol names in all uppercase. if you invert the case of all the
symbol names, you create a new dialect that doesn't talk to other Common
Lisp implementations. amazingly, there is no standard function to do
case conversion the way the symbol reader and printer does it, so you
have to call out to the reader or printer to get that behavior.
case is a personal preference in my view, and Common Lisp has done the
right thing in allowing each programmer the ability to choose his own
style. and it's not like it's a hard thing to change.
| It sure makes string comparison easier.
what does? case sensitivity or case insensitivity? I think the latter
is strongly preferable when dealing with protocol or user input. btw,
STRING= is case sensitive, while STRING-EQUAL is case insensitive.
Others have corrected your misunderstanding about Common Lisp's case
sensitivity (it's case sensitive internally, but canonicalizes case of
symbols on input by default). But to answer your second question, the
difference in how the reader processed the case of input never seemed to
hurt the popularity of Franz Lisp or Emacs Lisp, which both have
case-preserving readers (Franz's may have been configurable as well, but
if so the default was to preserve).
--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
> But to answer your second question, the
> difference in how the reader processed the case of input never seemed to
> hurt the popularity of Franz Lisp or Emacs Lisp, which both have
> case-preserving readers (Franz's may have been configurable as well, but
> if so the default was to preserve).
First, let's be clear: a case-preserving reader is nonconforming.
Programs which don't do anything tricky don't notice this
nonconformance, but programs that do will notice this nonconformance.
As with the Clinton situation (where some are blaming the rulemakers
and some are blaming the rulebreakers), so goes the situation with
this readtable issue. Some will blame the language designers and some
will blame the implementors who don't implement the designed language.
Hmm. I guess I've accidentally compared Clinton to Franz. That wasn't
really intentional, but now I'm left with an ethical dilemma between
apologizing for it and asking Harlequin if that's bonus-worthy.
Maybe I should take a poll. (No, just kidding. My mailbox is still
not clear of all the dozen or two e-mails that people sent telling me
the proper citation for "grok". Please no followup on my bad use of
metaphor.)
Anyway, what I started out to say was that (as anyone who's done
prioritization of bug reports knows), "frequency" of problems (and
consequently of pain felt and reported by users) is a
multi-dimensional quantity. Saying that something happens "a lot"
doesn't make clear what axis of this multi-dimensional quantity you're
saying has a high magnitude. For example, I was once at Symbolics
when just before a major release, I found a bug in special binding of
lambda variables in a lambda combination (not just a lambda
expression; in an actual ((lambda ...)...). "It's all packaged and
ready to ship," someone protested. "How frequently does the bug
happen?" What was I to answer? Every time anyone runs my code, I
told them. But then, I don't know how often they do that. Nor do I
know how many developers are like me. So at minimum frequency is "how
often is code developed which exercises a given bug" along one axis vs
"how often is code containing the buggy code executed" along another
axsis vs "how often in the buggy code that's being executed is the
path reached which tickles the bug". Maybe there are even more axes.
In the case in question, it just seemed embarrassing to have lambda
broken when you're a lisp machine company, so Symbolics fixed it. But
oddly enough, hardly anyone then or now used lambda combinations at
all, even though they're retained in the language. Most people use
LET instead. And of those, VERY few use specials in the binding
list because it's mostly classical programmers and scheme programmers
who like lambda combinations, and they all hate specials. So really
the bug was not likely to occur at all. Except when it did. And
then always. So it goes.
Why does all this matter? Well, I guess I'm just trying to point out
that while what Barry said is probably true--that it probably hasn't
materially hurt Franz's implementation in the market, it doesn't follow
that it doesn't cause individuals grief. I bet it probably has, though
I have no stats to back me up. And I just feel a little bad for
the people who do get hit by this that they ALSO find people implying
it's a matter of no consequence. To the people it happens to, it is
of consequence. Whether it's of consequence to the world that it's of
consequence to these people--well, there's an open question.
Emacs on the other hand is another story. Emacs is not part of any
standard and since the design choice is entirely arbitrary, I
absolutely agree with Barry that it can't hurt really either way.
The important thing is just that it's defined.
The problem in the CL case is that it's defined a certain way and
(to my understanding) Franz doesn't follow the standard.
I hope Franz doesn't feel I'm picking on them here. I don't try to
play any kind of marketing games here on comp.lang.lisp. At
Harlequin, we're basically content to just beat them in the
marketplace. In this forum I prefer a more collegiate atmosphere. So
much choice of them as an example is just because Barry raised the
issue and because it's one I felt commentworthy. Don't think I'm
telling you not to buy their products for the reasons I've cited
here. (There are plenty of other reasons I'd rather you use.
... heh ... sorry, couldn't resist.)
> Barry Margolin <bar...@bbnplanet.com> writes:
>
> > But to answer your second question, the
> > difference in how the reader processed the case of input never seemed to
> > hurt the popularity of Franz Lisp or Emacs Lisp, which both have
> > case-preserving readers (Franz's may have been configurable as well, but
> > if so the default was to preserve).
>
> First, let's be clear: a case-preserving reader is nonconforming.
> Programs which don't do anything tricky don't notice this
> nonconformance, but programs that do will notice this nonconformance.
Conforming to what standard? Common Lisp? Neither of the lisps
mentioned above are Common Lisps.
--
Duane Rettig Franz Inc. http://www.franz.com/ (www)
1995 University Ave Suite 275 Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)
well, they do now. although it doesn't appear they have forgiven me
completely for all the noise I made about it, ACL 5.0 does come with a
very significantly improved symbol reader and printer -- they both now
respect every relevant printer variable and print-read consistency is
maintained in all cases, which was not the case previously. I rolled my
own symbol reader and printer for ACL 4.3 because I got sufficiently
annoyed by the broken implementation then, but I'm happy to say that
that's history.
src.naggum.no/lisp/symbol-printer.cl (HTTP or FTP) has the code for ACL
4.3+, if anyone's interested. it's _very_ heavily optimized.
> Kent M Pitman <pit...@world.std.com> writes:
>
> > Barry Margolin <bar...@bbnplanet.com> writes:
> >
> > > But to answer your second question, the
> > > difference in how the reader processed the case of input never seemed to
> > > hurt the popularity of Franz Lisp or Emacs Lisp, which both have
> > > case-preserving readers (Franz's may have been configurable as well, but
> > > if so the default was to preserve).
> >
> > First, let's be clear: a case-preserving reader is nonconforming.
> > Programs which don't do anything tricky don't notice this
> > nonconformance, but programs that do will notice this nonconformance.
>
> Conforming to what standard? Common Lisp? Neither of the lisps
> mentioned above are Common Lisps.
Oh, he meant THAT Franz lisp. I know the dialect, but I assumed
he was referring to Allegro. Yes, I agree. non-CL's dont have
a conformance issue.
As to Allegro, I've heard tell it uses lowercase symbol names, which
would be a potential cause of portability problems, but I have no way
of confirming this because I don't have access to your/Franz's
products. If you'd like to correct my notion (and set the record
generally straight for others), I'd certainly welcome that. I'd
rather work with accurate info.
Of course, as I thought I (perhaps clumsily) mentioned, my prior
remarks were not aimed at Franz at all even though it was them I was
using as an example. It was just the example I (perhaps mistakenly)
thought was on the table when I went to react to and extend the
other comments on the subject.\
(Sorry about all the Clinton comparisons, too, btw. I compared
several other unrelated things to Clinton at dinner tonight and
realized this whole US government political nightmare, about which
I've been commenting in other online [non-newsgroup] forums is really
getting to me...)
> Oh, he meant THAT Franz lisp. I know the dialect, but I assumed
> he was referring to Allegro. Yes, I agree. non-CL's dont have
> a conformance issue.
>
> As to Allegro, I've heard tell it uses lowercase symbol names, which
> would be a potential cause of portability problems,
No, Allegro has two modes of operation that can be switched on
the fly. In the Common Lisp mode, symbol names are read and stored
as required in the Common Lisp spec (which may include lower case
symbols if they are escaped). Also, as Erik mentioned, we have had
some bugs in some of the readtable operations regarding downcasing,
*print-escape*, etc, and have finally fixed them as of 5.0.
> but I have no way
> of confirming this because I don't have access to your/Franz's
> products. If you'd like to correct my notion (and set the record
> generally straight for others), I'd certainly welcome that. I'd
> rather work with accurate info.
Sure; the linux version is freely available at our website and is
representative of (i.e. the same as) what you would get if you
were a customer (without the support) ...
> Of course, as I thought I (perhaps clumsily) mentioned, my prior
> remarks were not aimed at Franz at all even though it was them I was
> using as an example. It was just the example I (perhaps mistakenly)
> thought was on the table when I went to react to and extend the
> other comments on the subject.\
>
> (Sorry about all the Clinton comparisons, too, btw. I compared
> several other unrelated things to Clinton at dinner tonight and
> realized this whole US government political nightmare, about which
> I've been commenting in other online [non-newsgroup] forums is really
> getting to me...)
OK, no problem; perhaps we all have a little Clinton in us (did I just
say that?....)
> Sure; the linux version is freely available at our website and is
> representative of (i.e. the same as) what you would get if you
> were a customer (without the support) ...
Ah, you want me to run a 5th operating system on the computers in my
office. I agree that's -possible-....
> OK, no problem; perhaps we all have a little Clinton in us (did I just
> say that?....)
No, no. You're supposed to say: "The apology wasn't good enough.
Try again." ;-) But maybe you shouldn't. It could start a very
dark spiral that spends $40M the industry could better use on other
things.
Error: End of subthread reached.
You may continue by reading or replying to an unrelated post.
I was answering a question that I thought was about Lisp, not Common Lisp.
So I gave some examples of well-known Lisp dialects that are
case-preserving. I had initially started to include Multics Maclisp, which
perhaps would have made it really clear to you what I was doing, but I felt
that would be too obscure for most readers.
Others have already clarified that I was not referring to Allegro CL when I
said Franz Lisp (Kent, did you really think that *I* would be so
imprecise?).
>The problem in the CL case is that it's defined a certain way and
>(to my understanding) Franz doesn't follow the standard.
The case control features of the CL reader were added at the request of
Franz, Inc. IIRC, they were case-preserving by default (probably as a
result of their Franz Lisp heritage), but this was under control of
proprietary variables that could be changed to conform to the CL way. By
the time the ANSI standard came out I expect they changed the default and
switched over to the standard configuration mechanism (*PRINT-CASE* and
READTABLE-CASE).
> Scheme is not a dialect of Common Lisp. the common heritage, if any, is
> so old and so far removed from today's reality that we're almost talking
> about a missing link. Scheme owes more to Algol than to Lisp, in my
> view, just like Java owes more to Smalltalk than to C++. the syntactic
> similarity is irrelevant for meaningful comparisons. Scheme adherents
> want to tell you Scheme is a dialect of Lisp, but I don't get it.
Did you mean to say "Scheme is not a dialect of Lisp" rather
than "not a dialect of Common Lisp"? In any case, it's unlikely
that anyone has ever claimed Scheme was a dialect of Common Lisp.
> what
> do _they_ get from confusing people like that? is it a hope for a piece
> of the market that Common Lisp has created? some Lispers (well, at least
> one, but he's also a Schemer) will insist very strongly that Common Lisp
> is not the only Lisp to consider.
Well, I'll certainly insist that Common Lisp is not the only Lisp.
Even if Common Lisp were the only important Lisp today, there would
still be Lisp's history. Lisp, like Madonna, turns 40 this year.
(I'm assuming the anniversary conference is in the right year
rather than properly checking, though).
The phrase "dialect of Lisp" has been used for many years, and
"dialect of Lisp" was taken to be a fairly broad category.
It was natural to speak of Scheme as a dialect of Lisp, and
one even finds sub-varieties of Scheme (such as T) referred
to as "dialects of Lisp".
That's the way people in the Lisp world talked (and they still do,
though not quite so much as before). What did they mean by "dialect
of Lisp"? One way to find out is to look at how that phrase was used
and hence at what things were said to be dialects of Lisp. If we do
that, then it seems pretty clear that, as a matter of usage, Scheme is
a "dialect of Lisp".
But that way to talking about Lisp can mislead, and it even
became somewhat dangerous once standardisation began, because
some people claimed Lisp was just one language (albeit with
dialects) and so should have only one standard.
The US position in the ISO WG was that Lisp was a family of
languages, and I believe that position was correct. And so
(the argument went) there should not be a standard for "Lisp"
but only for specific Lisp-family languages. John McCarthy
said he would denounce any standard for "Lisp".
An observation that goes back to at least the 70s is that
so-called dialects of Lisp could be as different from each other
as different languages in (say) the Algol family. That's one
reason why "dialect of Lisp" can mislead. Another problem
with "dialect" is that dialects tend not to be taken as
seriously as languages, as in the quote about a language
being a dialect with an army.
So, all things considered, the "dialect of Lisp" way of talking
is probably more trouble than it's worth.
-- jd
but what _is_ the Lisp that both Scheme and Common Lisp are dialects of?
if there is no such thing (and I don't think there is, anymore, although
there might well have been in the distant past), then it is not useful to
talk about it. "dialect" is not a mark of independent quality in my view
and there's a weird interaction between "dialect of Lisp" and the effect
the mark has on various languages that claim it: one language may try to
capitalize on the work of another ("we're _all_ dialects"), yet it may be
used to reduce the value of the work of another at the same time ("we're
all _merely_ dialects").
* Erik Naggum <er...@naggum.no>
| some Lispers (well, at least one, but he's also a Schemer) will insist
| very strongly that Common Lisp is not the only Lisp to consider.
* Jeff Dalton <je...@gairsay.aiai.ed.ac.uk>
| Well, I'll certainly insist that Common Lisp is not the only Lisp.
the two words "to consider" is essential to what I wrote above. I know
that you go ballistic every time somebody forgets to mention the myriads
of other Lisps that you want us to remember, and that's why I attempted
to be very specific. I'm annoyed that you appear to continue unimpeded
with your standard rhetoric.
| So, all things considered, the "dialect of Lisp" way of talking is
| probably more trouble than it's worth.
I agree, including your argumentation.
> The phrase "dialect of Lisp" has been used for many years, and
> "dialect of Lisp" was taken to be a fairly broad category.
> It was natural to speak of Scheme as a dialect of Lisp, and
> one even finds sub-varieties of Scheme (such as T) referred
> to as "dialects of Lisp".
I was reading about Lisp for years before I discovered Common Lisp (in
the mid 80s, FWIW), so I associate the name "Lisp" with a language or set
of languages that predates Common Lisp. The first Lisp book I read used
MacLisp, but the first Lisp code I remember reading (in Byte) was for a
very small dialect that ran on a 16K TRS-80.
So I'm rather bemused by all this fuss.
> So, all things considered, the "dialect of Lisp" way of talking
> is probably more trouble than it's worth.
A good point well put.
--
Remove insect from address to email me | You can never browse enough
"Ahh, aren't they cute" -- Anne Diamond describing drowning dolphins
It may be like what a US Supreme Court justice said about obscenity: I
can't define it, but I know it when I see it.
I remember that there was a debate at one of the first Lisp Users and
Vendors conferences (perhaps the first one after the Symbolics Lisp Users
Group morphed into the Association of Lisp Users) about whether Dylan
should be considered a dialect of Lisp, even though they were abandoning
parentheses.
Not that anyone likely cares, but Perl (Perl 5, in particular, since almost
everything is first-class) comes pretty close to being a dialect of Lisp,
IMHO.
What is the English that both Cockney and American English are dialects of?
If you don't like the "dialect of X" terminology, then perhaps "member of
the X family" would be better, but in my mind they mean the same thing.
There's definitely some quality of Lispiness that Scheme, Common Lisp,
Emacs Lisp, Maclisp, and Dylan all share. Like the quote someone posted
about the dictionary definition of "dog", there's no hard-and-fast set of
required qualities that a Lisp must satisfy, but if you put enough features
together you get something that most of us would agree is a Lisp.
Dylan? I keep seeing people include Dylan in the list of "lisp languages".
Heck, Dylan doesn't even have Lots of Irritating Surpurfelous Parentheses.
What qualifies Dylan as a lisp? If you include it, why not Smalltalk? If you
include Smalltalk, why not C++?
Mike McDonald
mik...@mikemac.com
List processing is central in Dylan, but a tedious thing to do in C++. Thus
Dylan belongs to the Lisp clan, unlike C++. The syntax is just a shell.
List processing is the vital core of Lisp, so any language that is critically
based on list manipulation is a Lisp dialect. In C++ one needs templates and
similar advanced bloat stuff to get somewhere near that point. Let alone
functions as first-class objects, lambda calculus and the like which is all
alien to C++.
Klaus Schilling
that's pretty amusing, considering Larry Wall's explicit hatred for Lisp.
#:Erik
--
those who do not know Lisp are doomed to reinvent it
assuming this was as rhetorical as it seems, why is "the King's/Queen's
[British] English" the _obviously_ wrong answer?
| If you don't like the "dialect of X" terminology, then perhaps "member of
| the X family" would be better, but in my mind they mean the same thing.
it seems to mean the same thing only when X = Lisp. otherwise, it makes
no sense at all to claim they are the same. English is not a dialect of
Germanic, but it is a member of the Germanic language family. neither is
English a dialect of Indo-European.
#:Erik
--
ATTENTION, all abducting aliens! you DON'T need to RETURN them!
> > Heck, Dylan doesn't even have Lots of Irritating Surpurfelous Parentheses.
> > What qualifies Dylan as a lisp? If you include it, why not Smalltalk? If you
> > include Smalltalk, why not C++?
>
> List processing is central in Dylan, but a tedious thing to do in C++. Thus
> Dylan belongs to the Lisp clan, unlike C++. The syntax is just a shell.
> List processing is the vital core of Lisp, so any language that is critically
> based on list manipulation is a Lisp dialect. In C++ one needs templates and
> similar advanced bloat stuff to get somewhere near that point. Let alone
> functions as first-class objects, lambda calculus and the like which is all
> alien to C++.
Although I'd put Dylan in the Lisp family of languages[1], I think
including everything that can handle lists efficiently (syntax- and
semantics- wise, that is) into the Lisp language family is going a bit
to far. This would mean we'd have to include nearly all modern
functional programming languages (since list-comprehension monads are
arguably very powerful list manipulation constructs).
Although most of them were probably influenced by Lisp (especially Scheme),
I think they have gone a far way from being in the Lisp family, with their
static higher-order typing systems, lazy-evaluation, Monadic I/O systems,
even higher-order module systems.
I think the real family-membership-test of any language family is
looking at source-code produced for real-live programs in them. If
you find a large overlap in idioms, then either the programmer was
programming "Fortran in Lisp"(TM), or the languages are indeed members
of the same language family.
Regs, Pierre.
Footnotes:
[1] Remember also that Dylan at first _had_ prefix-syntax, and only
later on adopted a second, infix-like syntax, which was then adopted
as the primary, and finally only syntax. But semantically, Dylan is
very nearly a "streamlined" CLOS, with integration of type/class
hierarchy, and a number of annotation possibilities to simplify the
compilers task of optimizing the whole thing ;) (WARNING:
Oversimplification Alert!) But in giving up on prefix-syntax, Dylan
has gone a step too far for me ;)
--
Pierre Mai <de...@cs.tu-berlin.de> http://home.pages.de/~trillian/
"Such is life." -- Fiona in "Four Weddings and a Funeral" (UK/1994)
I didn't know about that. What is it that he hates about it? Presumably
not the lack of type declarations, the automatic memory management, nor the
ability to execute code generated on the fly (Perl has "eval"). Maybe the
references-based semantics (i.e. object pointers are implicit), since the
major semantic difference between Perl 5 and Lisp is the need to use
special syntax to create references to first-class objects. Or maybe he
just doesn't like traditional Lisp syntax.
I think that the discovery that the Perl, Dylan, and Java folks hit on is
that if you can get around many people's irrational bias against Lisp's
heavily parenthesized syntax, they actually like most of the remaining
features, which just make programming easier. Garbage collection was
probably just one of the many language features that has simply been
waiting for machine speeds to catch up -- none of the current generation of
new programmers remember the days when Lisp would hang for a minute or more
in GC, so they're not biased against this and enjoy not having to call
free(). I recall that when C++ first started gaining popularity, one of
the most frequent Usenet posts in its newsgroup was "where can I get a
class that implements garbage collection?", and soon classes that implement
reference counting or conservative GC were popping up right and left.
Similarly, draft ANSI C++'s STL is in the spirit of Common Lisp's sequence
functions, but goes even further in providing higher level data structures
(stacks, queues, sorted tables, etc.).
> but in practice I don't know of a single Scheme implementation
> > that does *NOT* use the same lexer for the user-visible READ procedure and
> > the reader buried in the LOAD procedure and the top-level REPL.
> Stalin uses different code to implement READ and to read in the source
> program. When the source program is read in, the reader keeps track of
> source file name, line, and character positions to include in error
> messages. READ does not do this. In fact, the source program reader
> doesn't produce a typical S expression. Rather it produces a structure
> of type S-EXPRESSION which includes the encapsulated file, line,
> and character position.
Just FYI, there's a debugging package for GCL that changes the
GCL (GNU Common Lisp, formerly [A]KCL) reader to do something
similar. And then, when executing, it can show you where you
are in the source in an Emacs window.
-- jeff
> * Jeff Dalton <je...@gairsay.aiai.ed.ac.uk>
> | Did you mean to say "Scheme is not a dialect of Lisp" rather than "not a
> | dialect of Common Lisp"? In any case, it's unlikely that anyone has ever
> | claimed Scheme was a dialect of Common Lisp.
>
> but what _is_ the Lisp that both Scheme and Common Lisp are dialects of?
You seem to be presupposing that Lisp, Scheme, and Common Lisp are
all on the same level. Is that how it works for natural languages?
Would one ask "Where is the Chinese that Mandarin and Cantonese
are dialects of?" with similar rhetorical intent?
(If they are, indeed, considered dialects -- I have not checked this.)
I would have thought that a language was an abstraction relative to
its dialects. All speakers would speak one dialect or another, even
if one dialect was considered more standard than the others.
In any case, I am not saying that "dialects of Lisp" is the right
way to describe these things, only that it is established usage.
One can still criticise it as using "dialect" in a nonstandard way,
if that's the case, or whatever. But if someone says "___ is a
dialect of Lisp", and we want to know whether they've said something
true or false, we need to understand how they were using "dialect of
Lisp".
> if there is no such thing (and I don't think there is, anymore, although
> there might well have been in the distant past), then it is not useful to
> talk about it. "dialect" is not a mark of independent quality in my view
> and there's a weird interaction between "dialect of Lisp" and the effect
> the mark has on various languages that claim it: one language may try to
> capitalize on the work of another ("we're _all_ dialects"), yet it may be
> used to reduce the value of the work of another at the same time ("we're
> all _merely_ dialects").
"Dialect of Lisp" has been, as still is, much used to refer to
languages in the Lisp family. That way of talking has some serious
problems, which is one reason I think the "family of languages"
approach is better. But since many people did, and still do, talk of
"dialects of Lisp", we may want to understand what they're saying.
At the same time, if we take "dialect of <language>" in a probably
more standard sense, then these languages are not "dialects of Lisp".
As many have noted for at least 20 years now, these so-called dialects
can be as different from each other as the things that are described
as different languages in, say, the Algol family; and the "different
languages" way of talking is at least less misleading (in addition to
whatever other advantages it might have).
> * Erik Naggum <er...@naggum.no>
> | some Lispers (well, at least one, but he's also a Schemer) will insist
> | very strongly that Common Lisp is not the only Lisp to consider.
>
> * Jeff Dalton <je...@gairsay.aiai.ed.ac.uk>
> | Well, I'll certainly insist that Common Lisp is not the only Lisp.
>
> the two words "to consider" is essential to what I wrote above. I know
> that you go ballistic every time somebody forgets to mention the myriads
> of other Lisps that you want us to remember, and that's why I attempted
> to be very specific. I'm annoyed that you appear to continue unimpeded
> with your standard rhetoric.
Well, since it seems to matter to you, I'm happy to say Common Lisp is
not the only Lisp *to consider* too.
Anyway, Saying that Lisp is a family of languages has a number of
advantages over talking of "dialects of Lisp", and members of a
family can be very different from each other.
The other alternative that sometimes occurs is to use "Lisp" to mean
only Common Lisp. I don't see anything wrong with that in contexts
where it will not be misunderstood: where it's clear that it's being
used just as a shorter way to refer to Common Lisp.
But I think it's a mistake to use "Lisp" in that way when it may be
misundrstood as referring to all of Lisp. This matters especially
when "Lisp" is being criticised, as it all too often is. It's fairly
common for people to say that "Lisp" is a too large a language, or
makes it too hard to deliver small applications, or has various other
problems. But often these claims are not true of Lisp in general
(some Lisps are very small languages, a Lisp could make it easy to
deliver small applications, and so on), but only of certain particular
Lisps (maybe Common Lisp), or only of certain implementations.
Another case where I disagree is where someone seems to go further
than using "Lisp" as conveniently short for "Common Lisp" and say that
Common Lisp is the only Lisp, or that "Lisp" just *means* common Lisp
(and hence that there's either no Lisp family or else no other
member).
For in fact other Lisps do exist, a number of them are still being
used, and Lisps can be significantly different from Common Lisp.
-- jd
> | If you don't like the "dialect of X" terminology, then perhaps "member of
> | the X family" would be better, but in my mind they mean the same thing.
>
> it seems to mean the same thing only when X = Lisp.
I think it most likely is the case that "dialect of Lisp",
in its "traditional" Lisp-world usage, employs a nonstandard
sense of "dialect". But that way of talking about Lisp-family
languages is so common that we're going to have to live with
it for some time to come.
> In article <31150180...@naggum.no>, Erik Naggum <er...@naggum.no> wrote:
> >* Barry Margolin <bar...@bbnplanet.com>
> >| Not that anyone likely cares, but Perl (Perl 5, in particular, since almost
> >| everything is first-class) comes pretty close to being a dialect of Lisp,
> >| IMHO.
> >
> > that's pretty amusing, considering Larry Wall's explicit hatred for Lisp.
>
> I didn't know about that. What is it that he hates about it? Presumably
> not the lack of type declarations, the automatic memory management, nor the
> ability to execute code generated on the fly (Perl has "eval"). Maybe the
> references-based semantics (i.e. object pointers are implicit), since the
> major semantic difference between Perl 5 and Lisp is the need to use
> special syntax to create references to first-class objects. Or maybe he
> just doesn't like traditional Lisp syntax.
>
And what about python, pike, ici and ruby ?
> I think that the discovery that the Perl, Dylan, and Java folks hit on is
> that if you can get around many people's irrational bias against Lisp's
> heavily parenthesized syntax, they actually like most of the remaining
> features, which just make programming easier. Garbage collection was
> probably just one of the many language features that has simply been
> waiting for machine speeds to catch up -- none of the current generation of
> new programmers remember the days when Lisp would hang for a minute or more
> in GC, so they're not biased against this and enjoy not having to call
> free(). I recall that when C++ first started gaining popularity, one of
> the most frequent Usenet posts in its newsgroup was "where can I get a
> class that implements garbage collection?", and soon classes that implement
> reference counting or conservative GC were popping up right and left.
> Similarly, draft ANSI C++'s STL is in the spirit of Common Lisp's sequence
> functions, but goes even further in providing higher level data structures
> (stacks, queues, sorted tables, etc.).
On my machine, Emacs lisp does hang for several minutes, the swapping noise
making the Wall s tremble.
Klaus Schilling
it doesn't seem that way to me. why does it seem that way to you?
| (If they [Mandarin and Cantonese] are, indeed, considered dialects [of
| Chinese] -- I have not checked this.)
they are not considered dialects of Chinese by the Chinese. Western
non-linguists appear to find "Chinese" a useful abstraction. it's about
as useful as "Germanic" about Western Hemisphere _spoken_ languages.
(Chinese the writing-system is of course a different matter altogether.)
| Anyway, Saying that Lisp is a family of languages has a number of
| advantages over talking of "dialects of Lisp", and members of a family
| can be very different from each other.
indeed. however, membership in the family should ideally be testable by
some reasonably simple means. I think the crucial element to membership
is whether source code can be read and represented internally in the
run-time environment as a standard data structure, and as a corollary,
whether one can expect READ and WRITE to exist and do the obvious thing
for all types that do not reflect "dynamic state" and without _undue_
complexity. that is, the old "code is data" argument. without that, I'd
say it doesn't matter _what_ you do to look like any member of the Lisp
family, and I'd have to remove Dylan and Perl 5 from the family.
| But I think it's a mistake to use "Lisp" in that way when it may be
| misunderstood as referring to all of Lisp. This matters especially when
| "Lisp" is being criticised, as it all too often is. It's fairly common
| for people to say that "Lisp" is a too large a language, or makes it too
| hard to deliver small applications, or has various other problems. But
| often these claims are not true of Lisp in general (some Lisps are very
| small languages, a Lisp could make it easy to deliver small applications,
| and so on), but only of certain particular Lisps (maybe Common Lisp), or
| only of certain implementations.
on this we agree. arguing _against_ Lisp has to be done on the essential
elements of similiarity, not against incidental differences or qualities
of implementations.
| Another case where I disagree is where someone seems to go further than
| using "Lisp" as conveniently short for "Common Lisp" and say that Common
| Lisp is the only Lisp, or that "Lisp" just *means* common Lisp (and hence
| that there's either no Lisp family or else no other member).
this would depend on context. in some contexts, it is destructive and
confusing to insist that "Lisp is not Common Lisp".
| For in fact other Lisps do exist, a number of them are still being used,
| and Lisps can be significantly different from Common Lisp.
while still being used, I cannot but argue against learning them apart
from the applications they are embedded in, such as Emacs' Lisp or
AutoCAD's Lisp.
I agree. Real world linguists presumably have terms for the various levels
in the language taxonomy, but most of us aren't linguists and aren't
familiar with the fine distinctions between the levels. To a linguist, "X
family" and "dialects of X" are almost certainly very different, I'm happy
to use them synonymously in reference to Lisp. I've also sometimes used
"flavor of Lisp" -- this has the advantage that it doesn't try to reuse an
existing linguistic term. Programming language people also often refer to
the "Algol family", which includes languages like Algol, PL/I, Pascal, Ada,
and C -- to me, what they have in common is similar uses of block
structuring, structured data, and expression syntax.
Another thing that also can be used to determine language family membership
is design history. This isn't something you can check by looking at a
language specification. But it's well known that Dylan was designed by
people very familiar with Lisp (many different dialects, and several of
them were involved with the original and/or X3J13 design of CL); they took
what they thought were all the good ideas from Lisp (call by object
reference, dynamic memory management, much of CLOS), renamed them as they
saw fit, added some other features (e.g. sealed classes), and eventually
replaced the Lisp-like syntax with something more Pascal-like. But
underneath that syntactic skin we all know there beats the heart of a Lisp.
I think they started with the following goal: knowing what we know now and
not having to worry about backward compatibility, redesign Lisp from
scratch. Backward compatibility is the main reason why the Common Lisp
designers couldn't do what the Dylan designers did -- CL was evolutionary,
while Dylan could be revolutionary.
Perl5 is a real pastiche. It adopts many syntactic features from C, Unix
shell, and sed/awk, and combines them with an underlying engine that's more
like Lisp, IMHO. Given its mix-and-match origin, it's hard to say that it
belongs to any particular family. But as a Lisp enthusiast, I don't feel
uncomfortable using it, the way I do when using C.
To me, more important than internal list processing is the fact that a
Lisp language syntax is based fundamentally on the list structure.
The fact that ``any Lisp program is itself a list'' is what makes powerful
macros like defpart possible, and for me this is the crucial feature which
makes Lisp the language of choice for doing any kind of real work in this
world.
--
David J Cooper Jr Genworks International
dcoo...@genworks.com http://www.genworks.com
...Embracing an Open Systems Approach to Knowledge-based Engineering...
I think he doesn't like the syntax.
> I think that the discovery that the Perl, Dylan, and Java folks hit on is
> that if you can get around many people's irrational bias against Lisp's
> heavily parenthesized syntax, they actually like most of the remaining
> features, which just make programming easier.
I'm not convinced about this. I don't have an irrational bias against
Lisp (my home computer is a 3630), and I certainly *do* have a bias
against perl, whose syntax makes me feel quite ill. But Perl gives me
important things that are hard to get in Lisp -- mostly string bashing
with good performance. If I wrote Java I'd get at least the promise
of feasible cross-platform GUI stuff. Those are both real immediate
benefits which it is quite hard to get from Lisp systems. In the case
of perl especially, I would (and have) write in lispy languages in
preference, if I could do so without struggling because my scripts are
so painfully slow.
(And before someone replies with `string processing in Lisp is easy,
you're an idiot blah blah': it really isn't that easy if you want
things to be fast, small and simple. I spent quite a long time doing
stuff in scsh, and I now have a bunch of (very pretty) scripts which
are really a pain in terms of performance compared to the obvious
rewrite in Perl. I've done the same in elk, and CL, and it just isn't
easy to get the kind of painless performance that perl has.)
--tim
strange. i love both of them, as former c but now lisp addict.
perl gives me all and 10x more what i could do in c plus most of the
lisp'ish constructs (eg: map, hashes) i love.
perl pleases my chaotic hacker mind and lisp my well-organized
intellectual mind.
as with tim,
I don't even try to do the string and database stuff in lisp what i do
now in perl since with perl it is much easier to write and it runs
faster. before the lisp has even initialized its image my perl script
has finished processing the ~100 textfiles.
and i still do like the one- or two-liners in perl, which would be six-
liners in lisp. still kind of beautiful in lisp but unavailable art.
readability (i mean perl's so claimed "non-readability") is relative.
yes, lisp is self-declarative, but i still can read and enhance my perl
scripts i wrote years ago.
i just make more errors in perl than in lisp. in lisp it's almost
impossible to make errors. in perl it's almost impossible to make no
errors at the first writing, but the compiler makes wonderful
suggestions. in c of course it's almost impossible to detect every
single error.
>But Perl gives me
>important things that are hard to get in Lisp -- mostly string bashing
>with good performance. If I wrote Java I'd get at least the promise
>of feasible cross-platform GUI stuff. Those are both real immediate
>benefits which it is quite hard to get from Lisp systems. In the case
>of perl especially, I would (and have) write in lispy languages in
>preference, if I could do so without struggling because my scripts are
>so painfully slow.
---
Reini Urban
http://xarch.tu-graz.ac.at/autocad/news/faq/autolisp.html
This would exclude McCarthy's original Lisp from the Lisp family! The fact
that Lisp programs could be represented as lists was a revelation that came
a few years later, when the EVAL function was written.
What are your tips and techniques for string processing in Lisp?
Where (and why) does Lisp lose and Perl win?
randy.
--
Randal N. Sims (Randy) | Tel: (803)725-1387
Westinghouse Savannah River Co. | Fax: (803)725-8829
SRS, 773-A, A1128, Rm. 2 | Email: randa...@srs.gov
Aiken, SC 29808-0001 USA | URL: http://www.srs.gov (generic)
DISCLAIMER: The opinions expressed are mine and do not necessarily
represent Westinghouse Savannah River Co. or the
United States Department of Energy.
John McCarthy went on record in comp.emacs when somebody wanted to
replace Lisp with Perl, saying, and I quote, hopefully sufficiently
accurately from dejanews, despite their tendency to view articles and
headers as subject to interpretation and layout control:
From: John McCarthy <j...@Steam.Stanford.EDU>
Date: 08 Feb 1998 00:00:00 GMT
Subject: Re: w3 and Re: perl embedded in emacs ("no zero-indexed char arrays")
Newsgroups: comp.emacs, comp.emacs.xemacs
Message-ID: <x4hk9b5...@Steam.Stanford.EDU>
One of the major characteristics of Lisp is that Lisp programs are
Lisp data and one can compute with Lisp programs present in the
machine without parsing. Scheme does this. Prolog does it to some
extent. The original version of the late Dylan language did this.
To what extent is this facility used in XEmacs Lisp? Macros use it,
and of course compilers do?
What about Perl?
--
John McCarthy, Computer Science Department, Stanford, CA 94305
http://www-formal.stanford.edu/jmc/progress/
He who refuses to do arithmetic is doomed to talk nonsense.
To a linguist, "family" tends to imply more difference than "dialect".
Nobody calls modern Italian, Spanish, or French dialects of some
language. On the other hand, there is no real dividing line between
two languages of one family and two dialects of one language. It's
partly mutual intelligibility and partly politics. ("Mutual
intelligibility" is also not well defined, nor can it be. There are
places where one basic language is spoken, each group can talk to
its neighbors, but the ends can't understand each other. This at
least used to be the case with the German-speaking Swiss down the
Rhine to the Netherlands.)
We're well in the mainstream here. We call various languages dialects
of Lisp on the basis of mutual intelligibility, and we have political
reasons to consider Scheme, Common Lisp, and ISLisp dialects of one
language. The folks who like Wirth-designed languages seem to have
political reasons for calling Modula-2 and Oberon different languages
from Pascal. Over in comp.lang.c, the regulars are fiercely
determined to call C and C++ two different languages, for reasons of
their own (independence, I think - sort of like whether Ukrainian is
a dialect of Russian).
So we don't need to feel guilty about misusing linguistic terms.
--
David H. Thornley | These opinions are mine. I
da...@thornley.net | do give them freely to those
http://www.thornley.net/~thornley/david/ | who run too slowly. O-
Perl has eval(). Perl is mainly a string-processing language, and Perl
programs passed to eval() are themselves strings. Many of the things one
needed eval() for in Perl4 have been replaced by explicit Perl5 operators
(e.g. in Perl4 I would implemented nested data structures by storing
variable names and evaling them, but Perl5 has references), but the
capability is still there.
> What are your tips and techniques for string processing in Lisp?
> Where (and why) does Lisp lose and Perl win?
String processing is, IMO, one of Lisp's weak points, but it's no worse
than most other languages. There is one language that no one here has
so far mentioned, and that is the string processing language Snobol4.
When written well, it's more readable than Perl. It would be fairly
straightforward to write a Snobol4 pattern matcher as a Lisp macro.
Incidentally, like Lisp and Perl, Snobol4 also has an eval which takes
a piece of Snobol4 (a string) and executes it.
> randy.
--
Le Hibou (mo bheachd fhe/in: my own opinion)
"it's just that in C++ and the like, you don't trust _anybody_,
and in CLOS you basically trust everybody. the practical result
is that thieves and bums use C++ and nice people use CLOS."
-- Erik Naggum
what is it that is so weak? I find it immensely useful that "string
operations" in other languages actually work on _sequences_ in Common
Lisp. on the other hand, that sometimes does make them harder to find
when you look specifically for string operations, and perhaps more so
when you need a few keyword arguments to get what you really want.
When I think about the common string operations I do in Perl, many of them
don't exist as Common Lisp (or most other Lisp) built-ins: pattern
matching, substring replacement, inserting and deleting, splitting on
delimiters, etc.
Of course, these can be written in CL, but in string-oriented languages you
don't have to do that. There may be a library of them already, but the
same would probably be true of other languages -- hence I agree with Donald
Fisk's point that "it's not worse than most other languages."
> * Donald Fisk <donal...@bt-sys.spamblock.bt.co.uk>
> | String processing is, IMO, one of Lisp's weak points, but it's no worse
> | than most other languages.
>
> what is it that is so weak? I find it immensely useful that "string
> operations" in other languages actually work on _sequences_ in Common
> Lisp. on the other hand, that sometimes does make them harder to find
> when you look specifically for string operations, and perhaps more so
> when you need a few keyword arguments to get what you really want.
I'm gonna side with Donald on this one. The absence of regular
expressions is a shame. Doing the equivalent with CL sequence
operations has the same feel as doing without FORMAT in I/O. The
language has the power even without FORMAT, but the packaging really
makes it easier to do and to spot bugs and to maintain/extend.
I programmed for a while intensively in MOO (a programming language for
certain text-based virtual realities) and it used regexps intensely and
they were a ton of fun to use compared to the CL alternatives.
I think the absence of them in CL is mostly an accident of history
because of when CL was coming together, not a willful rejection of a
good idea. Regexps hadn't caught on clearly enough by 1988 when we
froze the standard for there to be implementations which were
sporting them.
On the other hand, I've heard there are contributed libraries that
cover this gap. And given that, I can't feel too bad that what we have
is not useful.
I do also sometimes wish for the LispM's string-search-set and
string-search-not-set.
Gavin E. Gleason
Actually, i think Lisp is much better off than most other languages
for these tasks, but perhaps I have a different view of what
constitutes string processing. Lisp has an extensible syntax,
so one can define specialized languages specific to a task
that make it more useful and understandable than other languages,
at least once you become comfortable with parenthesis.
There are a few pattern matching packages for lisp. Take a look
at Olin Shivers package, it's quite good.
But if you take a broader view, you can simply do things easier
and better by not viewing the problem as a pattern matching problem,
but tackle it a different way. In particular, processing of HTML
documents using twisted pattern matching is particularly horrific
in my opinion. Instead, I tackle these tasks using an object
oriented approach -- convert HTML into objects, and then process
the objects, which is a much more general and MAINTAINABLE solution.
And if your object system is fast, then it's not really slow,
and in fact, compared to some highly compute intensive complex
pattern matching solutions, it may even be more efficient as well.
-Kelly Murray
;; this downloads a directory, and returns all the files as urls
(function url-directory (url)
(loop with anchors = nil
with html = (download-url url)
with tags = (parse-html html) ;; TURN HTML INTO OBJECTS
for tag in tags
finally (return (nreverse anchors))
do
(if (and (typep tag 'html-tag::A)
(slot-boundp tag 'href))
then
(push
(merge-urls (slot-value tag 'href) url)
anchors))
))
a _shame_? I don't consider regular expressions _that_ much of a must.
(I installed them in ACL 4.3, and it comes builtin with ACL 5.0, but I
haven't had occasion to use it, quite unlike in Emacs Lisp, where I have
to, and don't like the absence of everything that makes me have to.) on
the contrary, since their presence seem to supplant better solutions,
like parsers that convert strings into data structures you can work with
more intelligently, I find them akin to the mythological sirens whose
luring songs called ships into dangerous waters.
| I think the absence of them in CL is mostly an accident of history
| because of when CL was coming together, not a willful rejection of a good
| idea. Regexps hadn't caught on clearly enough by 1988 when we froze the
| standard for there to be implementations which were sporting them.
would it be a workable solution if the vendors cooperated on the
functional interface today? it doesn't appear to be for lack of fast and
good implementations, at least not as far as strings are concerned.
| I do also sometimes wish for the LispM's string-search-set and
| string-search-not-set.
hm. I found a veritable plethora of string functions in the Genera 7.2
manual set (which Michael Cracauer kindly sent me some time ago), most of
them seeming to _scream_ for far more general solutions (not counting
regexps as such a solution). it occurs to me that SEARCH should be
sufficient with some moderately simple functions, as in
(search (set <member>...) <string> :test #'in-set-p)
where SET and IN-SET-P could cooperate on optimizing performance, perhaps
even at compile time. I just don't want to limit this to strings, only.
likewise, regular expressions that worked on sequences of all kinds with
any type of contents would be _much_ more attractive to me. regular
expressions on strings is just that: a special case for _strings_, and
the pattern matching languages involved should be far more generally
applicable, in my opinion. it seems "un-Lispy" to me to make something
work only for strings when there is wider applicability.
> I didn't know about that. What is it that he hates about it? [...]
"Explicit hatred for Lisp" is way over the top - Larry probably
wouldn't deny that Perl owes quite a bit to Lisp.
The part that he probably has most problems with is the syntax. While
I personally like Lisp's syntax a lot, I still find most of Larry's
"linguistic" arguments quite compelling.
I didn't manage to dig up any references where he talks about Lisp
syntax specifically (someone has a very old comp.lang.perl archive?).
However, I recommend reading about his general approach to language
design under:
http://www.wall.org/~larry/natural.html
According to this, he would certainly like Common Lisp a lot better
than Scheme (for what it's worth).
--
Simon.
> What are your tips and techniques for string processing in Lisp?
> Where (and why) does Lisp lose and Perl win?
I think it's tempting to say at this point `because there is no
standard regexp/pattern-matching in Lisp'. But I think that is wrong
actually. There is at least one system (scsh) which has good
string-bashing stuff in there and some nice macrology on top of it
which makes things easy to do (there is an `awk' macro). And there is
an interesting proposal for lisp-style representations of regexps & so
forth which has been posted recently (I think by the scsh people).
And using a single-implementation system (like scsh or perl) is not a
problem for me so long as I have a reasonable expectation of being
able to port it to future machines.
I think the answer is actually poor I/O performance in many/all
Lisps. Again, I know that it is often *possible* to get good I/O
performance, but it usually isn't easy compared to things like perl.
In fact the particular case where I most recently got my fingers burnt
was really not string-bashing at all. Our dump scripts are currently
in scsh, and write a log file which is just a series of alists with
information about what was dumped & so forth. I then have a little
program which lets you ask various questions of this file, like `when
was the last level zero dump of this partition'. The log file gets
quite large (currently it's about 7000 records, or 0.5Mb), and there
is a search through the file to find information (so it obviously
won't scale for ever). The query program really just loops calling
READ. It's so slow that I typically start up an emacs, edit the file
and use search in emacs to find what I need to know. It takes minutes
to run. It isn't particularly cleverly written, but it isn't
*stupidly* written either. If I had written the log file in some
format that perl/awk could hack easily, a naive script to search it
would take fractions of a second. I suspect that I could implement
READ *in perl* and it would still be much faster.
This kind of thing is really bad news, and I've run across very
similar cases too many times. It's particularly bad news because
being able to mash large amounts of data sitting in files like this is
increasingly important to people. Of course, it's *possible* to do
this in Lispy languages, but it's hard enough that people won't do it.
When you have to think in terms of `I could link perl with my Lisp
image, then do the I/O using perl and just pass data back to Lisp
using some FFI' (I have thought this) you can be sure that Lisp will
not be used for these applications.
--tim
Larry Wall has been explicit in his hatred for Lisp, and has denied every
similarity between Perl and any Lisp. I have tried to communicate with
him, but because of my involvement with Lisp and Emacs and the FSF, got
an amazingly stupid flame back, not addressing anything of what I asked
him, and this was _before_ I looked closely enough at Perl to think it's
the worst disgrace of a language that has plagued this planet, not even
beaten by C++. he continued to attack Lisp whenever he had a chance, but
in all fairness, I haven't seen anything from him in a long time, so he
might have improved for all I care.
>I think the answer is actually poor I/O performance in many/all
>Lisps. Again, I know that it is often *possible* to get good I/O
>performance, but it usually isn't easy compared to things like perl.
>
>In fact the particular case where I most recently got my fingers burnt
>was really not string-bashing at all. Our dump scripts are currently
>in scsh, and write a log file which is just a series of alists with
>information about what was dumped & so forth. I then have a little
>program which lets you ask various questions of this file, like `when
>was the last level zero dump of this partition'. The log file gets
>quite large (currently it's about 7000 records, or 0.5Mb), and there
>is a search through the file to find information (so it obviously
>won't scale for ever). The query program really just loops calling
>READ. It's so slow that I typically start up an emacs, edit the file
>and use search in emacs to find what I need to know. It takes minutes
>to run. It isn't particularly cleverly written, but it isn't
>*stupidly* written either. If I had written the log file in some
>format that perl/awk could hack easily, a naive script to search it
>would take fractions of a second. I suspect that I could implement
>READ *in perl* and it would still be much faster.
>
maybe your problems arise because of using READ, which "interns" all symbols
and variables in scsh (READ is really a scheme parser). This is really
different from just finding strings in a text file by pattern matching.
Marc
--
------------------------------------------------------------------------------
email: marc dot hoffmann at users dot whh dot wau dot nl
------------------------------------------------------------------------------
> what is it that is so weak? I find it immensely useful that "string
> operations" in other languages actually work on _sequences_ in Common
> Lisp.
What you want to do with strings is often different from what you want
to do with lists, or vectors of numbers. Usually, some sort of lexical
analysis is required. This is built into Snobol and Perl, but to do the
same in Lisp would either require some extra programming, or worse,
some degree of cleverness.
To choose a specific example, here is the Snobol which can separate
a URL into a protocol, machine and path:
url arb . protocol "://" arb . machine "/" rem . path
Now, try doing that in one line of Lisp.
If this sort of thing comprises only a small part of your code,
but is used in several programs (a likely scenario), you're still better
off sticking to Lisp, after extending it with a macro which does
Snobol pattern matching.
> #:Erik
> maybe your problems arise because of using READ, which "interns" all symbols
> and variables in scsh (READ is really a scheme parser). This is really
> different from just finding strings in a text file by pattern matching.
yes, I know that. But using READ gives you a lot of useful stuff --
specifically it gives you a simple extensible data format for which
you don't have to write a parser (my specific example used essentially
a property list, with functions to handle the values keyed of the
property names and a default thing to handle unknown properties). It
would be a nice property of lisps if this was actually usable in
practice. The alternative is to go away and write a parser, which I
might as well do in perl.
--tim
Worst language EVER? I don't care for Perl, but certainly TCL and
C-shell are at least as horrid.
*********************************************
Semi-encrypted email address: p_o_m_i_j_e_ a_t_ i_n_a_v_ d_o_t_ n_e_t_
But I was actually not checking my facts carefully enough. READ *in
scsh* is very very slow, it does reasonably in other Lisps and
Schemes.
I did some small tests reading a 6800 record, 500k file (very few
distinct symbols, maybe 10):
Lisp system machine elapsed time
--------------------------------------------------
Genera 8.3 NXP 1000 40 secs (compiled)
CMUCL 18b Ultra 1/170 1.5 secs (variable between 1 and 2)
2.5 secs interpreted
scsh/s48 Ultra 1/170 57 secs
Allegro 4.3 Ultra 1/170 1.8 secs (variable)
2.8 secs interpreted
elk (version?) Ultra 1/170 about 4 secs (no timing tool in elk)
So it looks like scsh is pretty grim.
I still think that Lisps typically have weak I/O but obviously I was
overstating my case a bit. I know not to use scsh any more though!
--tim
this is a very limiting view.
| Usually, some sort of lexical analysis is required.
pattern matching should work for all types, not just characters, IMO.
| This is built into Snobol and Perl, but to do the same in Lisp would
| either require some extra programming, or worse, some degree of
| cleverness.
I fail to see the problem. this isn't exactly rocket science, so how
many times would you need to do it? on the other hand, I was afflicted
with the "don't make huge libraries yourself" illness for a long time,
since that's how one normally works under Unix. however, dumping a new
Lisp image with lots and lots of functions effectively makes them part of
the language, not your application.
| To choose a specific example, here is the Snobol which can separate
| a URL into a protocol, machine and path:
|
| url arb . protocol "://" arb . machine "/" rem . path
|
| Now, try doing that in one line of Lisp.
I'd say just (delimited-substrings url "://" "/"), but I assume the above
really sets a bunch of variables, as well, so let's make it
(multiple-value-bind (protocol host path) (delimited-substrings url "://" "/")
...)
by the way, this doesn't actually work for _URLs_. relative URLs fail,
the path actually _includes_ the slash, which might not even be present
to begin with. the "host" part may contain a username, a port, or both.
not all protocols have paths. not all URLs separate the protocol from
the first "argument" with double slashes -- the syntax simply says colon,
and parsing of the rest depends on the protocol.
_this_ is why such simple solutions are wrong, and the only reason people
choose them is because they don't understand the complexity of the issues
involved. good programmers acknowledge the complexity of the task and
handle the trivial cases as the special cases they are when worth it,
while bad programmers assume the trivial and special-case the rest.
regexps are usually valid only for the trivial cases, and they quickly
get so complex that one wonders what people were thinking when they did
_not_ return to the drawing board and get it right with a real parser.
| If this sort of thing comprises only a small part of your code, but is
| used in several programs (a likely scenario), you're still better off
| sticking to Lisp, after extending it with a macro which does Snobol
| pattern matching.
in this case, you're much better off writing a real parser for URL's.
not surprisingly, that is shorter in Lisp than in Perl when it follows
the _entire_ specification, not just the easy parts. and that's why I
hate Perl and love Lisp -- it's incredibly hard to do _all_ the work
correctly in Perl and know that you have done it, and it's no significant
extra cost in Lisp. this means that Perl attracts the quick and dirty
hackers, and Lisp those who want correctness, but what else is new?
on the other hand, I have made at least half a living from fixing other
people's incomplete code for one and a half decade, so the more Perl is
used, the more work I get to do over, after the poor client has learned
how complex the task really is, and can appreciate the correctness.
without Perl, I would have had to convince them myself... thanks, Perl!
> * Simon Leinen <si...@limmat.switch.ch>
> | "Explicit hatred for Lisp" is way over the top - Larry probably
> | wouldn't deny that Perl owes quite a bit to Lisp.
>
> Larry Wall has been explicit in his hatred for Lisp, and has denied every
> similarity between Perl and any Lisp. ...
Larry's book -- "Programming Perl", O'Reilly & Associates, 1990 -- surely
confesses an influence. He says at one point (p178) "That's what you get for
knowing just enough Lisp to be dangerous".
For the terminally curious, the example that causes him to say this is a code
snippet which unbuffers a chosen stream while maintaining the currently
selected stream:
local($oldfh) = select(STERR); $| = 1; select($oldfh)
He rewrites this as:
select((select(STDERR), $| = 1)[$[])
which causes him to compose the line I quoted above.
The Lispy equivalents would be something like:
(let ((oldfh (select *standard-error*)))
(unbuffer-selected-stream)
(select oldfh))
and
(select
(car
(list
(select *standard-error*) (unbuffer-selected-stream))))
Of course a 'real' Lisper would have written it as:
(select
(prog1
(select *standard-error*)
(unbuffer-selected-stream)))
__Jason
> Erik Naggum wrote:
> >
> > * Simon Leinen <si...@limmat.switch.ch>
> > | "Explicit hatred for Lisp" is way over the top - Larry probably
> > | wouldn't deny that Perl owes quite a bit to Lisp.
> >
> > Larry Wall has been explicit in his hatred for Lisp, and has denied every
> > similarity between Perl and any Lisp. I have tried to communicate with
> > him, but because of my involvement with Lisp and Emacs and the FSF, got
> > an amazingly stupid flame back, not addressing anything of what I asked
> > him, and this was _before_ I looked closely enough at Perl to think it's
> > the worst disgrace of a language that has plagued this planet, not even
> > beaten by C++. he continued to attack Lisp whenever he had a chance, but
> > in all fairness, I haven't seen anything from him in a long time, so he
> > might have improved for all I care.
> >
> > #:Erik
> > --
> > ATTENTION, all abducting aliens! you DON'T need to RETURN them!
>
> Worst language EVER? I don't care for Perl, but certainly TCL and
> C-shell are at least as horrid.
No, they are nowhere near as horrid as ba$ick, fortran , cobol and java.
Klaus Schilling
> * Donald Fisk <donal...@bt-sys.spamblock.bt.co.uk>
> | To choose a specific example, here is the Snobol which can separate
> | a URL into a protocol, machine and path:
> |
> | url arb . protocol "://" arb . machine "/" rem . path
> |
> | Now, try doing that in one line of Lisp.
>
> I'd say just (delimited-substrings url "://" "/"), but I assume the above
> really sets a bunch of variables, as well, so let's make it
>
> (multiple-value-bind (protocol host path) (delimited-substrings url "://" "/")
> ...)
I cannot find delimited-substrings in CLTL2. Is it something you
wroteyourself? If so, it proves my point: that you have to extend Lisp to
support
the string processing functionality built into Snobol.
> regexps are usually valid only for the trivial cases, and they quickly
> get so complex that one wonders what people were thinking when they did
> _not_ return to the drawing board and get it right with a real parser.
Agreed. Snobol patterns are, though, more flexible than the sort of
regular expressions built into Perl. For example, context sensitivity
presents no problem in Snobol, e.g.
input ":" len(1) $ x arb . output *x
finds a colon in whatever the user types in, and prints out everything
between the character after the colon (assigned to variable x) and the
next occurrence of it (e.g. if the inputs is "foo:bargackbaz" then the
output is "argack").
I am reliably informed that this sort of thing is less straightforward in Perl,
which makes one wonder "What is the point of Perl?" given that Snobol
already existed.
But it's still not as straightforward to do string processing in raw Common
Lisp as it is in Snobol.
> I hate Perl and love Lisp
At the risk of sounding like an AOL subscriber, "Me too". However,there are
other languages out there that are, for certain types of task
(in this case, Snobol for string processing), better than Lisp.
(CLtL2 is irrelevant. CLtL1 or ANSI CL are the reference documents.)
| Is it something you wrote yourself?
yes, but it's been dumped with my Allegro CL image for well over a year,
so it is in every way indistinguishable from the other elements of this
environment.
| If so, it proves my point: that you have to extend Lisp to support the
| string processing functionality built into Snobol.
well, you prove half your point but you ignore that you prove more than
half of my point at the same time, namely that programming in "Common
Lisp" is not just about the standard. "extending Common Lisp" is a piece
of cake -- it is far from trivial to extend Perl or C++ the same way,
although what's in Perl today is a testament to what people asked Larry
Wall to extend Perl to do, and C++ got is cancerous growth from Bjarne
Stroustrup's openness to any stray comer's wish. in both cases, however,
there's a market for all kinds of packages. clearly it is OK to "extend"
other languages. _somebody_ wrote those packages and they weren't turned
away. (in fact, a good argument against both languages is not _nobody_
gets turned away, except those who want clean design and correctness.)
why is it not OK with Common Lisp? why does everything have to be in the
ANSI Standard to be usable? give people a language they cannot adapt,
and they adapt it, but give them a language supremely adaptable, and they
cringe from _having_ to adapt it. I don't understand this.
or is it that Perl and C++ are such butt-ugly languages that nobody feels
intimidated by their grandness to feel they are not "worthy" of extending
them, while such an intimidation effectively prevents most people from
"extending" Common Lisp?
| I am reliably informed that this sort of thing is less straightforward in
| Perl, which makes one wonder "What is the point of Perl?" given that
| Snobol already existed.
to form a community of people who were left out of every other community,
namely system administrators who usually couldn't program _anything_ and
who were only interested in quick-and-dirty solutions that appeared to
keep the system up and runnding and themselves busy. Snobol couldn't do
that, and Common Lisp certainly cannot attract that crowd.
| However,there are other languages out there that are, for certain types
| of task (in this case, Snobol for string processing), better than Lisp.
only because somebody else went to the trouble of defining them for you.
I don't understand why this is such a big deal. Perl and C++ are _about_
people not getting what they want and going ahead to create it. now,
Perl and C++ are living proof of what happens when you feel like creating
a whole new language just to get a minute incremental benefits. Lisp
isn't like that. as much as I dislike Scheme for giving me a bucket of
sand and a furnace when I want a glass coffee mug, at least it embodies
the attitude that building something yourself and then strive to reuse it
is the right way to go. Common Lisp is the way it is for the same
reason, only people didn't have the needs that Perl satisfies. I don't
think this is a problem at all. if you have a problem to which Perl is
the best solution, you have at least two problems.
#:Erik
-------
(defun delimited-substrings (string &rest delimiters)
"Return as multiple values the substrings delimited by each delimiter."
(loop
with substrings = ()
for delimiter in delimiters
for start = 0 then (+ end length) ;after last delimiter ends
for end = (search delimiter string :start2 start)
for length = (length delimiter)
do (push (subseq string start end) substrings)
until (null end) ;the string was exhausted
finally
(when end ;the delimiters were exhausted
(push (subseq string (+ end length)) substrings))
(return (values-list (nreverse substrings)))))
> or is it that Perl and C++ are such butt-ugly languages that nobody feels
> intimidated by their grandness to feel they are not "worthy" of extending
> them, while such an intimidation effectively prevents most people from
> "extending" Common Lisp?
Maybe "butt-ugly" languages just cry out to be extended/enhanced. Maybe the
base language is so painful to use without other people's contributions that a
culture builds up in sharing "useful" bits of code. CL, on the other hand,
seems to be used for big projects that don't encourage sharing bits and
pieces. Most CL people seem to start every project with a clean lisp image.
>| However,there are other languages out there that are, for certain types
>| of task (in this case, Snobol for string processing), better than Lisp.
>
> only because somebody else went to the trouble of defining them for you.
> I don't understand why this is such a big deal.
Don't under estimate the attractiveness of having someone else write
something for you. There's "risk" in doing it yourself. If someone else writes
the code and it breaks, either they'll fix it or you can relish in one's own
smug superiority at the boob who couldn't even write a simple piece of code
correctly.
> #:Erik
> -------
> (defun delimited-substrings (string &rest delimiters)
> "Return as multiple values the substrings delimited by each delimiter."
Thanks for the tidbit of code. It's gone into my init.lisp file for CMUCL.
Got any other useful tidbits? :-)
Mike McDonald
mik...@mikemac.com
Erik> (defun delimited-substrings (string &rest delimiters)
Erik> "Return as multiple values the substrings delimited by each delimiter."
Erik> (loop
Erik> with substrings = ()
Erik> for delimiter in delimiters
Erik> for start = 0 then (+ end length) ;after last delimiter ends
Erik> for end = (search delimiter string :start2 start)
Erik> for length = (length delimiter)
Erik> do (push (subseq string start end) substrings)
Erik> until (null end) ;the string was exhausted
Erik> finally
Erik> (when end ;the delimiters were exhausted
Erik> (push (subseq string (+ end length)) substrings))
Erik> (return (values-list (nreverse substrings)))))
Hmm. I recently needed something like this for the Nth time and
finally cobbled something together that seems to work (see below). It
is derived from some string splitting code of Keith Waclena that I
found thanks to Altavista. I generalized it to work on sequences and
to optionally collapse adjacent delimiters. It has not been bummed
sufficiently to yield good performance and is a bit messy in sections,
but it has been working (seemingly) correctly in the applications I
have needed it for.
Sometimes the files I need to ingest are white-space delimited files
(where the quantity of white-space is irrelevant) and other times the
files are #\Tab delimited and the number of #\Tab's are relevant.
(defun split-sequence (delim seq &optional (collapse t))
"Split SEQ, returning a list of sequences corresponding to the
subsequences of SEQ which are separated by occurrences of DELIM. The
optional parameter COLLAPSE determines how multiple adjacent
instances of DELIM are treated. Non-nil (default) treats multiple
adjacent instances of DELIM as one delimiter. Nil treats each
instance of DELIM as a separate delimiter."
(flet ((split1 (delim seq collapse)
"SPLIT1 splits SEQ at the first occurrence of the
element DELIM, returning, as multiple values, the
subsequence upto but not including DELIM as the
first value, an indicator of lastness (by presence
of DELIM), and the subsequence from immediately
after DELIM and extending to the end of SEQ. If
the parameter COLLAPSE is non-nil, then leading
instances of DELIM are eaten first."
(let ((seq2 (if collapse
(let ((start (position-if-not
#'(lambda (val)
(eq delim val))
seq)))
(if start
(subseq seq start)
nil))
seq)))
(let ((pivot (position delim seq2)))
(if (null pivot)
(values seq2 t) ; no pivot delimiter so last is T
(values (subseq seq2 0 pivot)
nil ; pivot present so last is NIL
(subseq seq2 (1+ pivot))))))))
(if (= 0 (length seq))
nil
(multiple-value-bind (first last rest)
(split1 delim seq collapse)
(if (and collapse
(null first))
nil
(if last
(list first)
(if (or (null rest)
(= 0 (length rest)))
(if collapse
(list first)
(list first nil))
(cons first (split-sequence delim rest collapse)))))))))
--
Russell Senior
sen...@teleport.com
I haven't bothered reading CLtL1 in ages. I use ANSI CL if I want a
definitive statement of what's in the standard, but when I want something
easy to read I grab CLtL2 off my bookshelf. It's close enough for most
purposes.
>| If so, it proves my point: that you have to extend Lisp to support the
>| string processing functionality built into Snobol.
>
> well, you prove half your point but you ignore that you prove more than
> half of my point at the same time, namely that programming in "Common
> Lisp" is not just about the standard. "extending Common Lisp" is a piece
> of cake -- it is far from trivial to extend Perl or C++ the same way,
Just about every language allows libraries of functions to be used. But
there's still a qualitative difference between built-in features of the
language and libraries -- you can learn how to use the former from just
about any manual or textbook for the language. Any competent Perl
programmer would be expected to know about split() and regexps. Similar
libraries for Lisp can and have been written, but because they're not part
of the language there's not much consistency from site to site, so the
experience isn't very portable.
> although what's in Perl today is a testament to what people asked Larry
> Wall to extend Perl to do, and C++ got is cancerous growth from Bjarne
> Stroustrup's openness to any stray comer's wish. in both cases, however,
> there's a market for all kinds of packages. clearly it is OK to "extend"
> other languages. _somebody_ wrote those packages and they weren't turned
> away. (in fact, a good argument against both languages is not _nobody_
> gets turned away, except those who want clean design and correctness.)
What packages are you referring to in the case of Perl? Its string
handling is built in, and has been for years.
In addition, Perl is easily extended with libraries and modules. The
popularity of Perl has encouraged the formation of the CPAN, which
maintains a well-known module repository.
Erik> (defun delimited-substrings (string &rest delimiters)
Erik> "Return as multiple values the substrings delimited by each delimiter."
Erik> (loop
Erik> with substrings = ()
Erik> for delimiter in delimiters
Erik> for start = 0 then (+ end length) ;after last delimiter ends
Erik> for end = (search delimiter string :start2 start)
Erik> for length = (length delimiter)
Erik> do (push (subseq string start end) substrings)
Erik> until (null end) ;the string was exhausted
Erik> finally
Erik> (when end ;the delimiters were exhausted
Erik> (push (subseq string (+ end length)) substrings))
Erik> (return (values-list (nreverse substrings)))))
I have adapted Erik's code to a slightly different interface that I
find more useful. It takes only a single sequence element for a
delimiter, rather than the &rest arguments of Erik's function. Also,
it provides a switch to optionally aggregate adjacent delimiter
instances. Also, it returns the values as a list of subsequences,
rather than a multi-value return.
Sometimes the files I need to ingest are white-space delimited files
(where the quantity of white-space is irrelevant) and other times the
files are #\Tab delimited and the number of #\Tab's are relevant.
(defun split-sequence (seq delimiter collapse)
"Return list of subsequences in SEQ delimited by DELIMITER. A
non-nil value of COLLAPSE causes adjacent delimiters to be
aggregated."
(let (subseqs)
(if collapse
;; complicated case (delimiter aggregation)
(loop
for start = (position delimiter seq
:test-not #'eql
:start 0)
then (position delimiter seq
:test-not #'eql
:start end)
for end = (if start
(position delimiter seq :start start)
nil)
do
(when start
(push (subseq seq start end) subseqs))
until (null end)
finally
(when end
(push (subseq seq (position delimiter seq
:test-not #'eql
:start end)) subseqs)))
;; simpler case (no delimiter aggregation)
(loop
for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
do
(push (subseq seq start end) subseqs)
until (null end)
finally
(when end
(push (subseq seq (+ end 1)) subseqs))))
(nreverse subseqs)))
--
Russell Senior
sen...@teleport.com
I had hoped we could avoid re-stating the bloody obvious. the question
is whether it is part of the pragmatics of the language and whether it is
part of the culture of the language. the problem to solve is how this
came to be and what can be done about it if is not as we want it to be.
| Similar libraries for Lisp can and have been written, but because they're
| not part of the language there's not much consistency from site to site,
| so the experience isn't very portable.
I had also hoped you would have noticed that I tried to discuss some of
the explanations for this situation that had non-zero predictability for
the future, not just dead "facts". your statement is like saying "the
media focus heavily on Clinton these days".
| What packages are you referring to in the case of Perl?
tcp, various html tools, php, etc. don't pretend you don't know if you
at all know Perl.
| Its string handling is built in, and has been for years.
don't be so damn stupid.
| In addition, Perl is easily extended with libraries and modules.
ah, and Lisp isn't? come on, what's your agenda here? it certainly
isn't discussing anything intelligently even _close_ to the topic.
| The popularity of Perl has encouraged the formation of the CPAN, which
| maintains a well-known module repository.
I believe the popularity of Perl and CPAN have the same cause, and that
CPAN helped create the popularity much more than it was caused by it.
again, please try to understand that I'm trying to discuss the aspects of
languages that make people (1) believe they can be extended easily, and
(2) willing to use extensions. you appear more interested in stating the
bloody obvious and in defendng Perl. you have only succeeded in annoying
me with your inanities and bickering. I hope that satisfies you.
now, let's get back to why Lisp appears not to be extensible and why
people are so heavily focused on what's in the _standard_ in order to do
anything useful with Lisp.
#:Erik
that's pretty amusing -- the first few versions of this function did
indeed take a list of delimiters and return a list of values. however, I
have come to prefer multiple values to lists of values -- they are easier
to deal with when binding the result to variables, and especially when
just using the first value, which I found that I did quite often. I also
prefer to use APPLY when I already have a sequence, and when I was only
hacking out the first element of a delimited string, the list-as-argument
model became cumbersome.
I'd have implemented COLLAPSE with (delete "" substrings :test #'equal)
before reversing the list, and certainly made it optional once you make
the delimiters a list of its own. I agree that this flag is useful.
#:Erik
> to form a community of people who were left out of every other community,
> namely system administrators who usually couldn't program _anything_ and
> who were only interested in quick-and-dirty solutions that appeared to
> keep the system up and runnding and themselves busy. Snobol couldn't do
> that, and Common Lisp certainly cannot attract that crowd.
This reason can't be correct. System administrators can program
everything: you don't qualify to be one unless you're fluent in at
least 5 languages, not more than one of which can be an intercal
dialect. Most system administrators have at least one language
implementation to their credit.
Seriously: I am one of these people, and this argument doesn't hold
water. I'm completely competent in Common Lisp (and a good number of
other languages to a lesser degree, most of them not `scripting
languages'). But I still write perl when I need to, because it gets
the job done, and it performs well enough, and it talks to everything
painlessly. Yes, it is horrible, but I'm a utilitarian and so is
perl.
I guess the reason I don't use snobol (I have, but not for 10 years or
something) is because there's a larger available library for perl, and
I can ask lots of people questions. Neither of which reasons explain
why perl is more popular. I suspect that that has more to do with the
relatively painless move from awk/sed to perl, the fact that it's good
at talking to lots of other (Unix) tools, and the initial library was
quite large too. I forget too much snobol to know if it had any of
these features, but I suspect not. CL has the third, but the library
is not full of system-hacking stuff.
--tim
We were discussing "Why is Perl better than Lisp for string processing?"
I don't think it's "stupid" to believe that the existence of standard,
built-in, high-level string processing functions would be the reason for
this. It's the same reason why Lisp is better for applications that deal
with highly-interconnected networks of data. You can make the equivalent
of conses in Perl, but you'd still have to replicate all the higher-level
operations that come for free in Lisp.
Russell> I have adapted Erik's code to a slightly different interface
Russell> that I find more useful. It takes only a single sequence
Russell> element for a delimiter, rather than the &rest arguments of
Russell> Erik's function. Also, it provides a switch to optionally
Russell> aggregate adjacent delimiter instances. Also, it returns the
Russell> values as a list of subsequences, rather than a multi-value
Russell> return.
Erik> that's pretty amusing -- the first few versions of this
Erik> function did indeed take a list of delimiters and return a list
Erik> of values.
The applications I am finding for this tend to use the same delimiter
throughout the parent sequence. Of course, a delimiter specification
such as yours might prove useful in other more general circumstances.
Because of my own preconceptions, I was initially confused by the way
your function required the explicit provision of delimiters. Since in
my primary application 50 or 100 or more subsequences might be
returned, using that type of calling interface was going to be
impractical for me. On the return, I am less well-educated about the
relative merits of multiple-value returns compared to list of values,
so I chose the one I was more familiar with.
Erik> I'd have implemented COLLAPSE with (delete "" substrings :test
Erik> #'equal) before reversing the list, and certainly made it
Erik> optional once you make the delimiters a list of its own. I
Erik> agree that this flag is useful.
Hmm. I think your delete idea is an interesting solution that I
hadn't considered, but this specific suggestion would violate the
sequence abstraction in that the function would then only work on
strings. Perhaps (= (length subsequence) 0) would be a more general
and workable predicate. Removal of empty subsequences at the end
would eliminate the parallel construction, but might also lead to
unnecessary intermediate computations of subsequences in the collapse
case. It isn't immediately obvious to me which approach would be
faster.
Anyway, I want to thank you for posting your function. It provided a
much cleaner basis for my solution than the previous glob of goo that
I had scraped into a misshapen, though sputteringly useful, pile.
Thanks.
--
Russell Senior
sen...@teleport.com
this is quite interesting. I used it to hack apart ISO 8601 date and
time specifications (later writing a much more general parser for that
purpose), the "standard" Unix colon-separated lines, etc, where there
were obvious binding requirements for the return values, and fairly short
and simple argument lists. different needs produce different interfaces,
meaning it's going to be exceedingly hard to get the interface right.
this, too, could explain why what appears to be simple operations become
less simple in Lisp because the _general_ case is bigger in Lisp than in
other languages/tools.
| On the return, I am less well-educated about the relative merits of
| multiple-value returns compared to list of values, so I chose the one I
| was more familiar with.
I tend to use multiple values when I expect a list to be hacked apart as
soon as it is returned, and even more so when one value is more important
than the others, and thus more likely to be used by itself.
| Hmm. I think your delete idea is an interesting solution that I hadn't
| considered, but this specific suggestion would violate the sequence
| abstraction in that the function would then only work on strings.
good point, but then we should be specializing on lists, too, since they
have fairly different performance profiles from vectors/strings...
| Perhaps (= (length subsequence) 0) would be a more general and workable
| predicate.
that would be the same as (eq start end) before extracting the subseq,
and EQ is OK since we deal with fixnums. the COLLECT clause could then be
unless (and compact (eq start end))
do (push (subseq string start end) substrings)
this would be an inexpensive test.
| Anyway, I want to thank you for posting your function.
you're welcome. I hadn't expected this reception, to be honest. perhaps
there is hope for sharing Lisp code, after all. :)
#:Erik
Erik> good point, but then we should be specializing on lists, too,
Erik> since they have fairly different performance profiles from
Erik> vectors/strings...
Russell> Perhaps (= (length subsequence) 0) would be a more general
Russell> and workable predicate.
Erik> that would be the same as (eq start end) before extracting the
Erik> subseq, and EQ is OK since we deal with fixnums. the COLLECT
Erik> clause could then be
Erik> unless (and compact (eq start end))
Erik> do (push (subseq string start end) substrings)
Erik> this would be an inexpensive test.
Yes, `length' was the wrong predicate. I like your suggestion,
however, it has one problem. It does not handle the presence of
trailing delimiter elements neatly, because in that case `end' is NIL.
(split-sequence " this is a test " #\Space t)
=> ("this" "is" "a" "test" "")
The `Right Thing' IMO would be for the trailing empty subsequence to
disappear. My solution is to add another test to the unless clause
for (eq start len) where len is a precomputed length of the parent
sequence. It was also pointed out to me in email that the `finally'
clause is superfluous, so the new formulation is:
(defun split-sequence (seq delimiter &optional (collapse t))
"Return list of subsequences in SEQ delimited by DELIMITER. A non-nil
value of COLLAPSE causes adjacent delimiters to be aggregated."
(let (subseqs
(len (length seq)))
(loop
for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
unless (and collapse (or (eq start end)
(eq start len)))
do (push (subseq seq start end) subseqs)
until (null end))
(nreverse subseqs)))
This generates the `right' result in my test case:
(split-sequence " this is a test " #\Space t)
=> ("this" "is" "a" "test")
And it works on list sequences also:
(split-sequence '(0 1 2 3 0 0 4 5 0 6 7 0 8 9 0 0) 0 t)
=> ((1 2 3) (4 5) (6 7) (8 9))
(split-sequence '(0 1 2 3 0 0 4 5 0 6 7 0 8 9 0 0) 0 nil)
=> (NIL (1 2 3) NIL (4 5) (6 7) (8 9) NIL NIL)
The one remaining shortcoming of this function (for my purposes) is
that the code that calls this function expects the empty sequences to
be represented by NIL, rather than empty strings or vectors, for ease
in testing. This could be accomplished by inserting similar tests in
the push call. For example:
do (push (if (or (eq start end)
(eq start len))
nil
(subseq seq start end)) subseqs)
This gives:
(split-sequence " this is a test " #\Space nil)
=> (NIL "this" "is" "a" NIL "test" NIL)
Ahh... much better!
--
Russell Senior
sen...@teleport.com
Hi, while we are at sharing, I've rewritten the above to be completely
"loop-based" and to use NIL for empty subsequences:
(defun split-sequence (seq delimiter &optional (discard-empty-subseqs t))
"Return a list of subsequences in SEQ delimited by DELIMITER.
If discard-empty-subseqs is NIL, empty sub-sequences will be
represented as NIL, otherwise they will be discarded."
(loop for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
if (< start (or end (length seq)))
collect (subseq seq start end)
else unless discard-empty-subseqs collect nil
until (null end)))
cheers, Bernhard
--
--------------------------------------------------------------------------
Bernhard Pfahringer
Austrian Research Institute for http://www.ai.univie.ac.at/~bernhard/
Artificial Intelligence bern...@ai.univie.ac.at
BP> Hi, while we are at sharing, I've rewritten the above to be completely
BP> "loop-based" and to use NIL for empty subsequences:
BP> (defun split-sequence (seq delimiter &optional (discard-empty-subseqs t))
BP> "Return a list of subsequences in SEQ delimited by DELIMITER.
BP> If discard-empty-subseqs is NIL, empty sub-sequences will be
BP> represented as NIL, otherwise they will be discarded."
BP>
BP> (loop for start = 0 then (+ end 1)
BP> for end = (position delimiter seq :start start)
BP> if (< start (or end (length seq)))
BP> collect (subseq seq start end)
BP> else unless discard-empty-subseqs collect nil
BP> until (null end)))
One more refinement. It seems more natural for DISCARD-EMPTY-SUBSEQS
to default to NIL. While convenience will vary by user and
circumstance, it seems to me like an optional argument should be off
by default, so that:
(split-sequence seq delim) is eq to (split-sequence seq delim nil)
--
Russell Senior
sen...@teleport.com
> One more refinement. It seems more natural for DISCARD-EMPTY-SUBSEQS
> to default to NIL. While convenience will vary by user and
> circumstance, it seems to me like an optional argument should be off
> by default, so that:
>
> (split-sequence seq delim) is eq to (split-sequence seq delim nil)
>
If you're going to get refined :-), then you should also let the caller
specify the empty sequence marker: (just in case nil is a valid subseq.)
(defun split-sequence (seq delimiter
&optional (discard-empty-subseqs nil) (empty-marker nil))
"Return a list of subsequences in SEQ delimited by DELIMITER.
If discard-empty-subseqs is NIL, empty sub-sequences will be
represented as NIL, otherwise they will be discarded."
(loop for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
if (< start (or end (length seq)))
collect (subseq seq start end)
else unless discard-empty-subseqs collect empty-marker
until (null end)))
Mike McDonald
mik...@mikemac.com
This is all very interesting to read from a newbie lisp programmer
perspective. By the time the argument list reached that length I would
probably have used keyword arguments for discard-empty-subseqs and
empty-marker, instead of having to remember (more probably, look up)
the order. Would that be a good or bad thing stylistically, and
does it have performance implications?
(I know that the performance implications are probably not worth worrying
about unless you can demonstrate it's likely to be a bottleneck, but in
the general case, are they slower?)
-dan
There is some logic to having optional parameters be () by default -
especially for us old InterLisp hackers - but in this case the default
semantics indicates that the right answer is to change the parity of the
parameter altogether:
(defun split-sequence (seq delimiter &optional (keep-empty-subseqs nil))
"Return a list of subsequences in SEQ delimited by DELIMITER.
If keep-empty-subseqs is true, empty sub-sequences will be
represented as NIL, otherwise they will be discarded."
(loop for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
if (< start (or end (length seq)))
collect (subseq seq start end)
else when keep-empty-subseqs collect nil
until (null end)))
-- Harley
IMHO, it is a good thing for interfaces.
And yes, it will have some performance implications, but you should not
worry here because e.g. split-sequence is calling position (probably
more than once) with a keyword argument (:start), so if parsing keyword
arguments were a performance problem, you'd be hit seriously anyway.
The only worst case I can think of would be calling split-sequence
repeatly on empty sequences. There you might be able to measure
a speed difference attributable to &optional vs. &key.
In general, for me, interfaces get &key args, workhorses (especially
mutually recursive functions) get required arguments only.
To me, split-sequence is an interface, therefore you are right.
cheers, Bernhard
PS: and yes, I like the NIL defaults, and the EMPTY-MARKER addition.
I made empty-marker an optional only because discard-empty-subseqs was
already an optional. Mixing optionals and keys is very bad, IMNSHO. In this
case, they probably should be keys. discard-empty-subseqs and empty-marker are
exclusive of each other. If you want to specify the empty-marker, you're going
to want discard-empty-subseqs to be NIL. Having to specify the default
explicitly is silly. So it should be
(defun split-sequence (seq delimiter
&key (discard-empty-subseqs nil) (empty-marker nil))
"Return a list of subsequences in SEQ delimited by DELIMITER.
If discard-empty-subseqs is NIL, empty sub-sequences will be
represented as EMPTY-MARKER, otherwise they will be discarded."
(loop for start = 0 then (+ end 1)
for end = (position delimiter seq :start start)
if (< start (or end (length seq)))
collect (subseq seq start end)
else unless discard-empty-subseqs collect empty-marker
until (null end)))
Remembered to update the doc string this time!
Mike McDonald
mik...@mikemac.com