looking for a language with any of the following 4 charachteristics (all 4 would be nice).

9214 views
Skip to first unread message

zaphod

unread,
Feb 11, 2002, 8:48:16 PM2/11/02
to
My idea of the perfect language would be something like any of the
four following:

1)Logo that concentrated on lisp tricks and didn't even HAVE
turtle-graphics
2)Forth w/out all that OS STUFF, and stack STUFF.
3)lisp without so many parentheses
4)C without structured programming concepts

Anyone got a good candidate?

I'll even let you tell me how dumb I am for wanting what I want.
It seems that the common denominator of the four languages I like is
that they are all extensible, and I think all could be said to have
charachteristics of functional languages.

Someone could make me extraordinarilly happy by a real nice thorough
analysis of my essentially stupid and trivial thought(s) here.

Daniel Barlow

unread,
Feb 12, 2002, 4:57:53 AM2/12/02
to
Sla...@ureach.com (zaphod) writes:

> 1)Logo that concentrated on lisp tricks and didn't even HAVE
> turtle-graphics
> 2)Forth w/out all that OS STUFF, and stack STUFF.
> 3)lisp without so many parentheses
> 4)C without structured programming concepts

5) Assembler without all that addressing mode cruft

6) Plain txt fils without the lttr '', bcaus lts fac it, it's silly


-dan

--

http://ww.tlnt.net/cliki/ - Link farm for fr CL-on-Unix rsourcs

Raymond Wiker

unread,
Feb 12, 2002, 5:40:30 AM2/12/02
to
Daniel Barlow <d...@telent.net> writes:

> Sla...@ureach.com (zaphod) writes:
>
> > 1)Logo that concentrated on lisp tricks and didn't even HAVE
> > turtle-graphics
> > 2)Forth w/out all that OS STUFF, and stack STUFF.
> > 3)lisp without so many parentheses
> > 4)C without structured programming concepts
>
> 5) Assembler without all that addressing mode cruft
>
> 6) Plain txt fils without the lttr '', bcaus lts fac it, it's silly

^ You missed one.

Of the original list, the three first items seemed to be about
removing a (the) "defining feature" of the language - seems like a
pretty pointless exercise.

--
Raymond Wiker Mail: Raymon...@fast.no
Senior Software Engineer Web: http://www.fast.no/
Fast Search & Transfer ASA Phone: +47 23 01 11 60
P.O. Box 1677 Vika Fax: +47 35 54 87 99
NO-0120 Oslo, NORWAY Mob: +47 48 01 11 60

Try FAST Search: http://alltheweb.com/

Marco Antoniotti

unread,
Feb 12, 2002, 10:13:22 AM2/12/02
to

Sla...@ureach.com (zaphod) writes:

I think that by definition, INTERCAL (whose design goal was to remove
any feature known to any other programming language) fits the bill.

Cheers


--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Nils Goesche

unread,
Feb 12, 2002, 11:45:06 AM2/12/02
to
In article <y6cit92...@octagon.mrl.nyu.edu>, Marco Antoniotti wrote:
>
> Sla...@ureach.com (zaphod) writes:
>
>> My idea of the perfect language would be something like any of the
>> four following:
>>
>> 1)Logo that concentrated on lisp tricks and didn't even HAVE
>> turtle-graphics
>> 2)Forth w/out all that OS STUFF, and stack STUFF.
>> 3)lisp without so many parentheses
>> 4)C without structured programming concepts
>>
>> Anyone got a good candidate?
>>
>> I'll even let you tell me how dumb I am for wanting what I want.
>> It seems that the common denominator of the four languages I like is
>> that they are all extensible, and I think all could be said to have
>> charachteristics of functional languages.
>>
>> Someone could make me extraordinarilly happy by a real nice thorough
>> analysis of my essentially stupid and trivial thought(s) here.
>
> I think that by definition, INTERCAL (whose design goal was to remove
> any feature known to any other programming language) fits the bill.

No, he wants a functional language. So, I think this is closer:

http://www.eleves.ens.fr:8080/home/madore/programs/unlambda/

Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9

Eric Moss

unread,
Feb 12, 2002, 3:29:24 PM2/12/02
to
zaphod wrote:
>
> My idea of the perfect language would be something like any of the
> four following:
>
> 1)Logo that concentrated on lisp tricks and didn't even HAVE
> turtle-graphics
> 2)Forth w/out all that OS STUFF, and stack STUFF.
> 3)lisp without so many parentheses
> 4)C without structured programming concepts
>
> Anyone got a good candidate?

Yes.

Common Lisp comes closest for you, despite your loathing of
parentheses. First off, your dislikes wrt the other languages appear to
be structural and therefore unavoidable. Your beef with Lisp appears to
be cosmetic. That is least problematic when it comes to making a
working piece of code.

Addressing the parentheses phobia, which I see in other students in my
AI course, I say several things.

Firstly, parentheses are actually a necessity. You have to have *some*
delimiter in a language, after all, and it can't be just whitespace.

Secondly, parentheses are an *advantage* over other delimiters. Note
that C uses {} and ; and " " and ",", so it only *appears* to not be
full of delimiters. Lisp is far more elegant, separating tokens with
whitespace and expressions with ().

Thirdly, with a good editor, the parentheses become minor blips on your
screen, and the indentation (which is orthogonal to what makes parsing
easy for the compiler) can be your guide. If you wanted, you could even
customize the indentation, although lots of experience indicates that
emacs does just fine.

To summarize, Lisp appears to have everything you want except for its
cosmetic "flaw", which isn't really a flaw. That can be gotten past
with experience or editor-tinkering. All the other languages have major
structural issues that can't be avoided.


Or something like that...

Eric

Thomas F. Burdick

unread,
Feb 12, 2002, 4:42:58 PM2/12/02
to
Eric Moss <eric...@alltel.net> writes:

> zaphod wrote:
> >
> > My idea of the perfect language would be something like any of the
> > four following:
> >
> > 1)Logo that concentrated on lisp tricks and didn't even HAVE
> > turtle-graphics
> > 2)Forth w/out all that OS STUFF, and stack STUFF.
> > 3)lisp without so many parentheses
> > 4)C without structured programming concepts
> >
> > Anyone got a good candidate?
>
> Yes.
>
> Common Lisp comes closest for you, despite your loathing of
> parentheses. First off, your dislikes wrt the other languages appear to
> be structural and therefore unavoidable. Your beef with Lisp appears to
> be cosmetic. That is least problematic when it comes to making a
> working piece of code.
>
> Addressing the parentheses phobia, which I see in other students in my
> AI course, I say several things.
>
> Firstly, parentheses are actually a necessity. You have to have *some*
> delimiter in a language, after all, and it can't be just whitespace.

Hell, since the parens are just the textual way of representing the
structure of the code, you could use a structure editor and never see
another paren again. Writing said editor is left as an exercise to
the reader.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Erik Naggum

unread,
Feb 12, 2002, 5:16:14 PM2/12/02
to
* Eric Moss <eric...@alltel.net>

| Addressing the parentheses phobia, which I see in other students in my AI
| course, I say several things.

I wonder if it is the parentheses or the enclosing delimiter. For some
time, now, I have been trying to understand how people react to Lisp, and
something occurred to me some tima ago that was recently reinforced. In
almost all other programming languages, parentheses are actually painful,
or symptoms of something painful. E.g., in those stupid infix syntaxes,
you need parentheses when the precedences of the operators you want to
combine are not related the way you want them to be. So the parentheses
become a means of resolving a conflict between the language and your
needs. In C-style languages, where type casts are necessary due to the
retarded type system, parentheses are used to resolve a conflict between
what the language thinks should be the type of something and what you
want it to be. The number of parentheses thus correlate with the level
of complexity, and the level of complexity with how hard it is to grasp.
The only "neutral" parentheses are those used in function calls. The
rest of the delimiters serve different purposes and also look different.

However, in (Common) Lisp, parentheses are the only game in town (well,
this is not true, but to the extent they are, bear with me), and all the
emotionsl responses to parentheses-as-pain-indicators from languages that
the programmer may have been previously exposed to come right back at him
at a very low level of consciousness. Any thinking person would observe
his reaction and think about it, but thinking peopla are never a problem.
Those who only react and feel that something must be wrong with all the
parentheses, may have a very particular reaction to parentheses. I have
had occasion to exploit this recently to test the hypothesis.

< and > are accetable delimiters these days, so I changed the reader and
printer to use them instead of ( and ). (The only practical problem was
that symbols with < and > in them needed to have that character escaped.)
Presented to two people who had previously been negative to Lisp, one of
them thought it was OK, now, the other went "you can't trick me into
liking Lisp". Presented to three people who were predicted to have a
strong dislike of parentheses, but had not had prior exposure to Lisp,
all three found it interesting, and one thought the parentheses of the
original code looked silly when presented with it -- the others quickly
figured out what the point of the exercise was, but did not react with
hostility to the parentheses. I found only one person whom I thought
would not be hostile to parentheses, but he was hostile to all the HTML
crap, instead, effectively being more annoyed with <> than with ().
This, of course, serves no useful statistical purposes, but I do not want
to run a research project on this. I would like to experiment with
working with this syntax for a while just to see how I think it works,
however. It might actually be the easiest way to get around the
parenthesis "perception problem".

/// 2002-02-12
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Software Scavenger

unread,
Feb 13, 2002, 1:41:34 AM2/13/02
to
Erik Naggum <er...@naggum.net> wrote in message news:<32225409...@naggum.net>...

> I wonder if it is the parentheses or the enclosing delimiter. For some
> time, now, I have been trying to understand how people react to Lisp, and

My first reaction to Lisp parentheses before I started learning Lisp
was that there were three main reasons why I didn't like them. First,
I saw long strings of them in Lisp and wondered if I was expected to
count them every time I saw them, or how I could be sure they were
right without counting them. Second, parentheses are awkward on most
keyboards. They're more likely to be fumbled more often, because of
the combination of the shift key, the distance to the parentheses
keys, and the awkward combination of fingers used to type them.
Third, it seemed to me that infix syntax was making compilers do more
work to reduce the amount of work done by the programmer, and that
therefore the non-infix parentheses-based syntax was a way of taking
some of the work load off the compiler and putting it on the
programmer.

Holger Schauer

unread,
Feb 13, 2002, 5:33:27 AM2/13/02
to
On 12 Feb 2002, Software Scavenger wrote:
> Erik Naggum <er...@naggum.net> wrote in (some) message:

>> I wonder if it is the parentheses or the enclosing delimiter.
>> For some time, now, I have been trying to understand how people
>> react to Lisp, and
> First, I saw long strings of them in Lisp and wondered if I was
> expected to count them every time I saw them, or how I could be sure
> they were right without counting them.

That was the one thing I really hated in the intro-course on Lisp that
I have taken. Once I learned the joys of Emacs (some five years
later), the parentheses "problem" disappeared without a trace. Hence,
the first thing I actually showed my students this year was a really
awkward and painful written peace of Lisp code. Next, I showed them
what it would look like to write it in Emacs. I then turned to show
them the same code with parens removed and told them not to count
parens but to use the structure of the code. Now that the course is
done, most of the code they've written actually looks pretty lispy.

> Second, parentheses are awkward on most keyboards. They're more
> likely to be fumbled more often, because of the combination of the
> shift key, the distance to the parentheses keys, and the awkward
> combination of fingers used to type them.

You should take a look at a German keyboard and try the key
combinations necessary to insert curly braces. Alt-Gr-7 and 8. Now
that's awkward (and the reason why German programmers sometimes prefer
using qwerty keyboards over German qwerty ones).

Holger

--
--- http://www.coling.uni-freiburg.de/~schauer/ ---
Fachbegriffe der Informatik - Einfach erklärt
49: Version x.0
Kostenpflichtiger Preview als Bestandteil unserer Beta-Tests
(Kristian Köhntopp)

Brian Campbell

unread,
Feb 13, 2002, 10:25:41 AM2/13/02
to
In article <42e37222.02021...@posting.google.com>,
Sla...@ureach.com (zaphod) wrote:

> My idea of the perfect language would be something like any of the
> four following:
>
> 1)Logo that concentrated on lisp tricks and didn't even HAVE
> turtle-graphics
> 2)Forth w/out all that OS STUFF, and stack STUFF.
> 3)lisp without so many parentheses
> 4)C without structured programming concepts
>
> Anyone got a good candidate?

Well, to respond to exactly what you've asked for, I'd recommend Dylan
(which is a descendant of lisp with infix syntax) or ML (which is a
functional programming language with infix syntax, although it may seem
more weird to you than Dylan).

For Dylan, see the pages of the two implementations:
http://www.gwydiondylan.org (the open source implementation)
http://www.fun-o.com (the commercial implementation)

A web search should suffice for finding out stuff about ML (I've found
that when doing web searches about Dylan, I find lots of out of date
pages, so you have to know where to look to find the decent information).

>
> I'll even let you tell me how dumb I am for wanting what I want.
> It seems that the common denominator of the four languages I like is
> that they are all extensible, and I think all could be said to have
> charachteristics of functional languages.

Other languages you might want to consider but I can't say much about
are Oz/Mozart, Erlang, Haskell, Mercury, Smalltalk, or Self.

Of course, as plenty of other people have pointed out, the parentheses
in lisp really aren't that much of a problem, and lisp is far more
mature and complete than any of these other languages I've pointed out.
I've found that as I look at the newest features people are adding to
other languages and the problems people are encountering, they all seem
to have been solved in Lisp 20 years ago (that may be a slight
exaggeration, but not much of one).

Actually, though it makes me shudder to recommend it, the feature set of
perl seems to be slowly converging on an infix lisp, but perl is not a
language I'd recommend for anyone who wants anything close to resembling
elegance


>
> Someone could make me extraordinarilly happy by a real nice thorough
> analysis of my essentially stupid and trivial thought(s) here.

--
Brian Campbell
Real email: lambda (at) cs (dot) dartmouth (dot) edu

Ed L Cashin

unread,
Feb 13, 2002, 9:04:45 PM2/13/02
to
Erik Naggum <er...@naggum.net> writes:

...


> I would like to experiment with
> working with this syntax for a while just to see how I think it works,
> however. It might actually be the easiest way to get around the
> parenthesis "perception problem".

I don't know. Holger Schauer has a point: emacs makes it easy to edit
lisp, but many people don't use emacs. If I didn't already feel
confident that emacs will keep track of the parens and the indentation
for me on first encountering lisp, the nesting might appear
overwhelming.

Also, I remember thinking that lisp looked like "text vomit" compared
to languages whose structure lexically mirrors what's going on.
Here's an example in ruby:

{
"foo" => "bar",
"baz" => "burfle",
}.each { |i|
puts i
}

Which, once you're used to it, looks at a glance like a hash table
followed by some code to do for each thing in it. More importantly,
even before you're used to it, the structure suggests that there's
some structured data on top and some code on the bottom.

Lisp is more verbose, and at a glance always looks like text and
parentheses:

(let ((h (make-hash-table)))
(setf (gethash "foo" h) "bar")
(setf (gethash "foo" h) "bar")
(maphash
#'(lambda (k v)
(format t "~A~%" k)
(format t "~A~%" v)) h))

I know that an experienced lisper could create a read macro to support
a syntax like in the first example, but someone encountering lisp for
the first time might not know that.

My first time seeing a large amount of lisp code was in the emacs
sources.

--
--Ed L Cashin | PGP public key:
eca...@uga.edu | http://noserose.net/e/pgp/

zaphod

unread,
Feb 13, 2002, 10:06:23 PM2/13/02
to
Raymond Wiker <Raymon...@fast.no> wrote in message news:<86pu3br...@raw.grenland.fast.no>...

> Daniel Barlow <d...@telent.net> writes:
>
> > Sla...@ureach.com (zaphod) writes:
> >
> > > 1)Logo that concentrated on lisp tricks and didn't even HAVE
> > > turtle-graphics
> > > 2)Forth w/out all that OS STUFF, and stack STUFF.
> > > 3)lisp without so many parentheses
> > > 4)C without structured programming concepts
> >
> > 5) Assembler without all that addressing mode cruft
> >
> > 6) Plain txt fils without the lttr '', bcaus lts fac it, it's silly
>
> ^ You missed one.
>
> Of the original list, the three first items seemed to be about
> removing a (the) "defining feature" of the language - seems like a
> pretty pointless exercise.


I think I mentioned that! I covered all that junk. You probably read
the meat and ignored my side dishes! Don't eat ever eat in the
restaurant I want to own, or I might put a little surprise in the
secret sauce!
Thank you for replying!

zaphod

unread,
Feb 13, 2002, 10:08:06 PM2/13/02
to
Marco Antoniotti <mar...@cs.nyu.edu> wrote in message news:<y6cit92...@octagon.mrl.nyu.edu>...

> Sla...@ureach.com (zaphod) writes:
>
> > My idea of the perfect language would be something like any of the
> > four following:
> >
> > 1)Logo that concentrated on lisp tricks and didn't even HAVE
> > turtle-graphics
> > 2)Forth w/out all that OS STUFF, and stack STUFF.
> > 3)lisp without so many parentheses
> > 4)C without structured programming concepts
> >
> > Anyone got a good candidate?
> >
> > I'll even let you tell me how dumb I am for wanting what I want.
> > It seems that the common denominator of the four languages I like is
> > that they are all extensible, and I think all could be said to have
> > charachteristics of functional languages.
> >
> > Someone could make me extraordinarilly happy by a real nice thorough
> > analysis of my essentially stupid and trivial thought(s) here.
>
> I think that by definition, INTERCAL (whose design goal was to remove
> any feature known to any other programming language) fits the bill.
>
> Cheers

Intercal is a joke. I'm very stupid; but I'm just smart enough to know that!

Wade Humeniuk

unread,
Feb 13, 2002, 10:11:56 PM2/13/02
to

"Ed L Cashin" <eca...@uga.edu> wrote in message
news:863d04e...@cs.uga.edu...

>
> Also, I remember thinking that lisp looked like "text vomit" compared
> to languages whose structure lexically mirrors what's going on.
> Here's an example in ruby:
>
> {
> "foo" => "bar",
> "baz" => "burfle",
> }.each { |i|
> puts i
> }
>
> Which, once you're used to it, looks at a glance like a hash table
> followed by some code to do for each thing in it. More importantly,
> even before you're used to it, the structure suggests that there's
> some structured data on top and some code on the bottom.
>

I have a dumb question, but of what use is the preceding Ruby code? I do
not even see the hash table in that code, where is it and how do you refer
to it outside the code fragment? Overloading of {??

> Lisp is more verbose, and at a glance always looks like text and
> parentheses:
>
> (let ((h (make-hash-table)))
> (setf (gethash "foo" h) "bar")
> (setf (gethash "foo" h) "bar")
> (maphash
> #'(lambda (k v)
> (format t "~A~%" k)
> (format t "~A~%" v)) h))
>

All your ruby code above seems to do is

(write '((foo bar) (baz burfle)))

or more tersely

'((foo bar) (baz burfle))

Wade


zaphod

unread,
Feb 13, 2002, 10:16:06 PM2/13/02
to
Eric Moss <eric...@alltel.net> wrote in message news:<3C697B24...@alltel.net>...


From experience (very little, but it don't take more)it is not just
cosmetic to me! If it were just a matter of making sure you close all
of your parentheses; that would be fine (i've figured that out, just
close with a zero, on a count-down from all open parentheses), but the
problem is, I think you have to know the whole damned kit-and kaboodle
to know WHEN to open, and WHEN to close; either that or I have yet to
find anything that adresses the idea behind the opening and closing of
them.

Ed L Cashin

unread,
Feb 13, 2002, 10:20:55 PM2/13/02
to
"Wade Humeniuk" <hume...@cadvision.com> writes:

> "Ed L Cashin" <eca...@uga.edu> wrote in message
> news:863d04e...@cs.uga.edu...
> >
> > Also, I remember thinking that lisp looked like "text vomit" compared
> > to languages whose structure lexically mirrors what's going on.
> > Here's an example in ruby:
> >
> > {
> > "foo" => "bar",
> > "baz" => "burfle",
> > }.each { |i|
> > puts i
> > }

...


> I have a dumb question, but of what use is the preceding Ruby code? I do
> not even see the hash table in that code, where is it and how do you refer
> to it outside the code fragment? Overloading of {??

It simply illustrates that the code that creates a hash tables is
visually reminiscent of the relationships that the hash table
represents. To keep track of the variable for later you'd just use a
variable:

h = {


"foo" => "bar",
"baz" => "burfle",
}.each { |i|
puts i
}

h.each { |i| puts i } # or whatever you want to do with h


The lisp example did the same thing as the ruby example -- creating a
hash table and printing its contents. But my point was the visual
impact of the syntax and had nothing to do with the use of the example
code.

> > Lisp is more verbose, and at a glance always looks like text and
> > parentheses:
> >
> > (let ((h (make-hash-table)))
> > (setf (gethash "foo" h) "bar")
> > (setf (gethash "foo" h) "bar")
> > (maphash
> > #'(lambda (k v)
> > (format t "~A~%" k)
> > (format t "~A~%" v)) h))
> >
>
> All your ruby code above seems to do is
>
> (write '((foo bar) (baz burfle)))
>
> or more tersely
>
> '((foo bar) (baz burfle))

True.

zaphod

unread,
Feb 13, 2002, 10:23:28 PM2/13/02
to
Erik Naggum <er...@naggum.net> wrote in message news:<32225409...@naggum.net>...

Not with me. I have no problem with parentheses, except that I don't
know all the rules to their use, and I don't want to learn the entire
common-lisp language to find out; either. I may do so, but I WILL
find a better way, if I can!

zaphod

unread,
Feb 13, 2002, 10:31:37 PM2/13/02
to
Brian Campbell <lambd...@yahoo.com> wrote in message news:<lambda2000-0F772...@merrimack.dartmouth.edu>...


Thank You very much. I'm quite pleased. Have you checked out python, by the way?

Ed L Cashin

unread,
Feb 13, 2002, 11:09:56 PM2/13/02
to
Sla...@ureach.com (zaphod) writes:

...


> Not with me. I have no problem with parentheses, except that I
> don't know all the rules to their use, and I don't want to learn the
> entire common-lisp language to find out; either. I may do so, but I
> WILL find a better way, if I can!

As far as this lisp beginner can tell, it's pretty simple:

* parentheses go around a list

* when a list is evaluated the first thing is treated as a function
and the following things in the list are the function arguments.

There are abbreviations (like the single quote character) and special
cases (special forms), and extensions (like read macrose), but that
seems to be the general idea. Add the fact that lists can be elements
a list, and you're off!

Marc Spitzer

unread,
Feb 13, 2002, 11:36:40 PM2/13/02
to

Here are the rules that work for me, a begining lisper working on small
stuff, probably not the real reason but it has worked so far:

name ; it gets evaled no parens
(function_name ; it get evaled as a function, because it is the first
; thing that lisp sees after a open paren

Some thing like cond conditions or let apear different, they start with 2
parens, but that is because there is some stuff going on behind the seens.
With cond I think the first form is just checked for a boolena return value
so you need to scope what is checlked by wrapping it in a set of parens,
unless you are checking the value of a varable then you can just type it.
There I have contradicted my self, it is time to shut up now.

so the short answer is when you need a function use a paren and when it is
done close it.

good luck

marc

Tim Bradshaw

unread,
Feb 14, 2002, 6:58:57 AM2/14/02
to
* Ed L Cashin wrote:

> It simply illustrates that the code that creates a hash tables is
> visually reminiscent of the relationships that the hash table
> represents. To keep track of the variable for later you'd just use a
> variable:

> h = {
> "foo" => "bar",
> "baz" => "burfle",
> }.each { |i|
> puts i
> }

> h.each { |i| puts i } # or whatever you want to do with h


> The lisp example did the same thing as the ruby example -- creating a
> hash table and printing its contents. But my point was the visual
> impact of the syntax and had nothing to do with the use of the example
> code.

Yes, I think this is what Lisp is about. Languages like Perl or Ruby
(or C) have decided that one sort of thing is interesting, and have a
syntax which has been greatly optimized for that single thing. Perl
is *really good* at string-bashing code with regexps, C is really good
at very terse OS code that both runs and can be compiled in reasonable
time on a PDP11-class machine, and so on.

Lisp has decided not to decide. Rather than provide a great mass of
syntactic tricks to support some particular style or programming
technique, Lisp provides a minimalist syntax which is just adequate to
express nested structures of various kinds without making any
commitment as to their meaning. The programmer then decides what this
syntax means in any instance.

Lisp is a toolkit for language design not a toolkit for solving
problems in particular domain. Of course, people will typically
evolve special languages in Lisp if they need to spend enough time in
any one domain to make it worth while, but since those languages are
usually application specific and not well-known, it's always easy to
demonstrate that any given language has a better syntax for any given
application than Lisp does.

--tim

Erik Naggum

unread,
Feb 14, 2002, 8:12:00 AM2/14/02
to
* Ed L Cashin <eca...@uga.edu>

| Also, I remember thinking that lisp looked like "text vomit" compared
| to languages whose structure lexically mirrors what's going on.

It appears warranted by the various reactions people have posted and told
of elsewhere to conclude that Common Lisp is a language that is better
suited for those who are more verbal than visual in how they remember and
learn. Those who are more visual, tend to be thrown off by the lack of
visual clues and the preponderance of words they need to recognize in
order to "see" the structure. The verbal, who recognize words the way
the visual see pictures and figures, have no such problem.

However, since XML and the like is not the disaster it should have been,
I guess that either those who use it are completely clueless verbally as
well as visually (95% chance of being true) or people can learn to be
more verbal even if they are "naturally" visual (5% chance of being true).

This is not to imply that those who are more verbal than visual are
superior beings, but they are clearly more suited to certain tasks than
those who are more visual.

///

Erik Naggum

unread,
Feb 14, 2002, 8:15:22 AM2/14/02
to
* Sla...@ureach.com (zaphod)

| Not with me. I have no problem with parentheses, except that I don't
| know all the rules to their use, and I don't want to learn the entire
| common-lisp language to find out; either. I may do so, but I WILL
| find a better way, if I can!

Quite amazing. It is obviously superfluous to answer any of your
questions with technical answers. This is good to know.

///

Tim Bradshaw

unread,
Feb 14, 2002, 8:33:29 AM2/14/02
to
* Erik Naggum wrote:

> It appears warranted by the various reactions people have posted and told
> of elsewhere to conclude that Common Lisp is a language that is better
> suited for those who are more verbal than visual in how they remember and
> learn. Those who are more visual, tend to be thrown off by the lack of
> visual clues and the preponderance of words they need to recognize in
> order to "see" the structure. The verbal, who recognize words the way
> the visual see pictures and figures, have no such problem.

I think this is an interesting point. However I'm not sure it's right
or at least not uniquely right. I think I'm a terribly visual person
(although I also can read). Whenever I write systems in Lisp (or any
other language, but my only recent experience of non-trivial systems
is Lisp), I end up with a huge mass of throwaway `browser'-type tools
which show me pictures of the various structures in the system. I
find it fairly hard to work without these tools. One of the beauties
of Lisp, for me, is that it's so good at talking about complex data
structures, and that typically it's easy to get pictures of these
things of various kinds.

--tim

Holger Schauer

unread,
Feb 14, 2002, 8:43:10 AM2/14/02
to
On Thu, 14 Feb 2002, Erik Naggum wrote:
> * Ed L Cashin <eca...@uga.edu>
>| Also, I remember thinking that lisp looked like "text vomit"
>| compared to languages whose structure lexically mirrors what's
>| going on.

I think the structure of Lisp does mirror what's going on.



> It appears warranted by the various reactions people have posted
> and told of elsewhere to conclude that Common Lisp is a language
> that is better suited for those who are more verbal than visual in
> how they remember and learn. Those who are more visual, tend to
> be thrown off by the lack of visual clues and the preponderance of
> words they need to recognize in order to "see" the structure. The
> verbal, who recognize words the way the visual see pictures and
> figures, have no such problem.

I wonder on what basis you draw the conclusion that the distinction is
between verbal and visual and wonder even more about the possible
implications. For instance, a verbal learner should not be thrown off
by code like (member (car (list (do-something here (based on another
complicated computation) ... <bunch of further arguments elided>)))).
This seems counterintuitive to me, I think even experienced Lisp
programmers tend to have (reading) problems with such gross code. [1]

With respect to the more visual oriented, I think what helped me most
was to recognize that there is structure but that parentheses are not
an issue one needs to care about, as long as you do follow it. I think
Graham has an example in his "Ansi CL" book in which he presents some
Lisp code with and without the parens. It's getting the structure that
matters, not the parens. I think, a claim somebody made is likely to
be true across most programming languages, which is that it does not
really matter what style you're following, it's following the style
that matters [2].

But then again, I may be one of those who you would classify as a
visual oriented person, although I tend to see myself as being verbal
oriented. Come to think of it, I'm a very unlikely candidate for
participating in an obfuscated code contest, although I am uncertain
whether that tells a story or doesn't.

Holger

Footnotes:
[1] Some time ago, I made some whitespace modifications to some old
and very ugly looking code. I was not the only one feeling that the
result was much more readable afterwards.

[2] Of course, when you have to follow some style guideline enforced
by external forces, this may throw you off when its totally against
your personal preferences.

"/home/moehwald > echo "the quick brown fox jumps over the lazy dog" |
tr -d aeiou"
"Jetzt weiss ich endlich, wie ein gewisser A.K. seine Postings erstellt."
-- Sven Geggus in de.comp.os.unix.linux.misc

Marco Antoniotti

unread,
Feb 14, 2002, 8:58:25 AM2/14/02
to

Sla...@ureach.com (zaphod) writes:

> Marco Antoniotti <mar...@cs.nyu.edu> wrote in message news:<y6cit92...@octagon.mrl.nyu.edu>...

...

> > I think that by definition, INTERCAL (whose design goal was to remove
> > any feature known to any other programming language) fits the bill.
> >
> > Cheers
>
> Intercal is a joke. I'm very stupid; but I'm just smart enough to
> know that!

Given your username.... :)

42

Ed L Cashin

unread,
Feb 14, 2002, 9:03:09 AM2/14/02
to
Tim Bradshaw <t...@cley.com> writes:

...


> Yes, I think this is what Lisp is about. Languages like Perl or
> Ruby (or C) have decided that one sort of thing is interesting, and
> have a syntax which has been greatly optimized for that single
> thing. Perl is *really good* at string-bashing code with regexps, C
> is really good at very terse OS code that both runs and can be
> compiled in reasonable time on a PDP11-class machine, and so on.
>
> Lisp has decided not to decide. Rather than provide a great mass of
> syntactic tricks to support some particular style or programming
> technique, Lisp provides a minimalist syntax which is just adequate
> to express nested structures of various kinds without making any
> commitment as to their meaning. The programmer then decides what
> this syntax means in any instance.

Yes, and I think that's why it often requires a little bit of
experience with several programming that are good in a more limited
domain before lisp's generality can be recognized as a boon.

Marco Antoniotti

unread,
Feb 14, 2002, 9:10:19 AM2/14/02
to

Ed L Cashin <eca...@uga.edu> writes:

> Erik Naggum <er...@naggum.net> writes:
>
> ...
> > I would like to experiment with
> > working with this syntax for a while just to see how I think it works,
> > however. It might actually be the easiest way to get around the
> > parenthesis "perception problem".
>
> I don't know. Holger Schauer has a point: emacs makes it easy to edit
> lisp, but many people don't use emacs. If I didn't already feel
> confident that emacs will keep track of the parens and the indentation
> for me on first encountering lisp, the nesting might appear
> overwhelming.
>
> Also, I remember thinking that lisp looked like "text vomit" compared
> to languages whose structure lexically mirrors what's going on.
> Here's an example in ruby:
>
> {
> "foo" => "bar",
> "baz" => "burfle",
> }.each { |i|
> puts i
> }

(map* #'print
(make-hash-table* '(("foo" => "bar")
("baz" => "bar"))))

Hello!!!!!!

The point being that in CL you can modify the language, and make it
look like CL or something else.

Here is one of my favourite `primes' in conforming CL.

(in-package "SETL-USER")

(defun primes (max)
[n in (range 3 max 2)
/ (not (exist m in (range 3 (min (1- n) (+ 2 (sqrt n))) 2)
/ (= (mod n m) 0)))])

> I know that an experienced lisper could create a read macro to support
> a syntax like in the first example, but someone encountering lisp for
> the first time might not know that.

So? Does that warrant the application of Greenspun's Tenth? :)

> My first time seeing a large amount of lisp code was in the emacs
> sources.

A lot of ELisp code is not all that nice looking. Especially because
a lot of ELisp code does not (require 'cl) :)

Cheers

Christophe Rhodes

unread,
Feb 14, 2002, 9:17:32 AM2/14/02
to
Marco Antoniotti <mar...@cs.nyu.edu> writes:

> Here is one of my favourite `primes' in conforming CL.
>
> (in-package "SETL-USER")
>
> (defun primes (max)
> [n in (range 3 max 2)
> / (not (exist m in (range 3 (min (1- n) (+ 2 (sqrt n))) 2)
> / (= (mod n m) 0)))])

I appreciate the point, but I thought that we decided that "conforming
CL" programmes needed to include their macros and reader-macros to be
properly conforming... :-)

Christophe
--
Jesus College, Cambridge, CB5 8BL +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/ (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)

Erik Naggum

unread,
Feb 14, 2002, 9:20:22 AM2/14/02
to
* Holger Schauer <Holger....@gmx.de>

| I wonder on what basis you draw the conclusion that the distinction is
| between verbal and visual and wonder even more about the possible
| implications.

Sigh. I wrote:

It appears warranted by the various reactions people have posted and
told of elsewhere to conclude that Common Lisp is a language that is
better suited for those who are more verbal than visual in how they
remember and learn.

| For instance, a verbal learner should not be thrown off by code like


| (member (car (list (do-something here (based on another complicated
| computation) ... <bunch of further arguments elided>)))). This seems
| counterintuitive to me, I think even experienced Lisp programmers tend to
| have (reading) problems with such gross code. [1]

On what basis do you conclude something about what a "verbal learner"
should or should not be thrown off by?

| But then again, I may be one of those who you would classify as a
| visual oriented person

Why do you think this is an either-or issue? When I write "more verbal
than visual" and try to be very clear that we are talking about a point
on a line between two extrama, please do not waste my time by assuming
that only the extrema are worth talking about. Nobody is "classified" as
a visual-oriented person, it is a matter of what you are more comfortable
with, not some one-bit flag in your personality.

Thom Goodsell

unread,
Feb 14, 2002, 9:32:23 AM2/14/02
to
Holger Schauer <Holger....@gmx.de> writes:
>
> I wonder on what basis you draw the conclusion that the distinction is
> between verbal and visual and wonder even more about the possible
> implications. For instance, a verbal learner should not be thrown off
> by code like (member (car (list (do-something here (based on another
> complicated computation) ... <bunch of further arguments elided>)))).
> This seems counterintuitive to me, I think even experienced Lisp
> programmers tend to have (reading) problems with such gross code. [1]
>
> With respect to the more visual oriented, I think what helped me most
> was to recognize that there is structure but that parentheses are not
> an issue one needs to care about, as long as you do follow it. I think
> Graham has an example in his "Ansi CL" book in which he presents some
> Lisp code with and without the parens. It's getting the structure that
> matters, not the parens. I think, a claim somebody made is likely to
> be true across most programming languages, which is that it does not
> really matter what style you're following, it's following the style
> that matters [2].
>

I don't believe Erik intended to suggest that verbal people can easliy
read poorly formatted code. Rather, lisp code is more about words than
about granting special meaning to every non-text character on your
keyboard. As a simple example, consider array access in Lisp and
C/C++/Java:

(aref *some-array* 10)
vs.
some_array[10];

In C, the braces take the place of "aref" and are easily spotted, even
by someone who has trouble spotting "aref" in a mass of text. Thus,
discounting syntactic characters (parens, semi-colons, and braces), C
code has a lot more non-character symbols than Lisp. The structure is
still important in both cases.

I show the extreme example of a visually-oriented language, but I've
so far managed to avoid learning any Perl.

Thom

--
(map 'string #'(lambda (char) (let ((char-code (char-code char)))
(code-char (if (< 64 char-code 123) (+ (mod (+ 13 char-code) 52) 65)
char-code)))) "Z...@IXG.IUS")

Julian Stecklina

unread,
Feb 14, 2002, 10:15:35 AM2/14/02
to
Sla...@ureach.com (zaphod) writes:

[...]

> Intercal is a joke. I'm very stupid; but I'm just smart enough to know that!

But it's nevertheless interesting. I got headache after the first few
pages of the "specification". :)

Regards,
Julian

--
Um meinen oeffentlichen Schluessel zu erhalten:
To get my public key:
http://math-www.uni-paderborn.de/pgp/

Dorai Sitaram

unread,
Feb 14, 2002, 10:26:39 AM2/14/02
to

I am inclined to agree, but just yesterday a coupla
posts here were praising special tools over
general tools. That also sounded somewhat agreeable
with at the time, except that their argument put CL
firmly on the side of the specializers, not
generalizers as the above seems to be doing (unless
Lisp is not being equated with CL).

--d

Holger Schauer

unread,
Feb 14, 2002, 10:05:08 AM2/14/02
to
On Thu, 14 Feb 2002, Erik Naggum wrote:
> * Holger Schauer <Holger....@gmx.de>
>| I wonder on what basis you draw the conclusion that the distinction
>| is between verbal and visual and wonder even more about the
>| possible implications.
>
> Sigh. I wrote:
>
> It appears warranted by the various reactions people have posted
> and told of elsewhere to conclude that Common Lisp is a language
> that is better suited for those who are more verbal than visual
> in how they remember and learn.

Yes, I actually read what you wrote but was not sure what exactly the
various reactions have led you to this conclusion, as I have
difficulties -- given what I've read in this thread -- to arrive at
the same.



>| For instance, a verbal learner should not be thrown off by code
>| like (member (car (list (do-something here (based on another
>| complicated computation) ... <bunch of further arguments
>| elided>)))). This seems counterintuitive to me, I think even
>| experienced Lisp programmers tend to have (reading) problems with
>| such gross code. [1]
>
> On what basis do you conclude something about what a "verbal
> learner" should or should not be thrown off by?

Good question. I was in fact just reacting to the second half of your
paragraph, substituting "visual learner" for your "those who are more
visual":

>> Those who are more visual, tend to be thrown off by the lack of
>> visual clues and the preponderance of words they need to
>> recognize in order to "see" the structure. The verbal, who
>> recognize words the way the visual see pictures and figures,
>> have no such problem.

As I said, I was wondering whether my "conclusion" would be a valid
implication of the distinction you put forward. It doesn't seem to be,
though. The question then is whether I'm bashing a strawmen or not (I
don't intend to).



>| But then again, I may be one of those who you would classify as a
>| visual oriented person
>
> Why do you think this is an either-or issue? When I write "more
> verbal than visual" and try to be very clear that we are talking
> about a point on a line between two extrama, please do not waste
> my time by assuming that only the extrema are worth talking about.
> Nobody is "classified" as a visual-oriented person, it is a matter
> of what you are more comfortable with, not some one-bit flag in
> your personality.

Yes, this is certainly true. However, I was wondering whether I'm as
verbal as I think I am and whether that leads me to some fast (and
wrong) conclusions.

Holger

Holger Schauer

unread,
Feb 14, 2002, 10:19:03 AM2/14/02
to
On 14 Feb 2002, Thom Goodsell wrote:
> I don't believe Erik intended to suggest that verbal people can
> easliy read poorly formatted code. Rather, lisp code is more about
> words than about granting special meaning to every non-text
> character on your keyboard.

Well, yes, I agree with that largely. I would not go as far as saying
that words don't matter in other languages (but then nobody said that,
either). They do matter, of course, as much as in CL, minus you've got
to get those non-text characters right first :-) Syntax can be pretty
annoying, but after all, it's just syntax, not semantics.

More to the point though, even if, in CL, words matter "more" than
other things, formatting still is an important matter. But formatting,
or structure, is clearly an issue of visually grasping what's going
on. That's an important support to (verbally) understanding code.

I hasten to add (that I believe) that throwing a bunch of non-text
characters all over the place to further enhance such support is
misguided.

> The structure is still important in both cases.

Exactly my point.

Holger

Tim Bradshaw

unread,
Feb 14, 2002, 10:48:56 AM2/14/02
to
* Dorai Sitaram wrote:

> I am inclined to agree, but just yesterday a coupla
> posts here were praising special tools over
> general tools. That also sounded somewhat agreeable
> with at the time, except that their argument put CL
> firmly on the side of the specializers, not
> generalizers as the above seems to be doing (unless
> Lisp is not being equated with CL).

If you are referring to the article I wrote where I said I didn't try
and write general libraries or tools, then that's not quite what I was
trying to say.

What I meant was that doing `library standard' or `language standard'
systems is, in my opinion, very hard indeed (and many of the so-called
`standard libraries' such as, for instance, the Win32 API are in my
opinion good examples of systems which are *failing* to be good enough
and thus require endless reinvention).

I'm all in favour of general tools (which should be library/language
standard), and I think that CL is a very good example of such a
general tool whose design is actually adequate in almost all areas
(that is meant to be very high praise: there aren't any bits of CL
which I find unusably badly designed, which is not something I've come
across very often).

*But*, since I think that design of general tools is so hard, or at
least it is hard for me, I tend to not try, but instead to design
special tools for the job at hand. That way I actually get the job
done.

So I wasn't making a value judgement, more trying to describe how I
work.

--tim


Marco Antoniotti

unread,
Feb 14, 2002, 11:26:34 AM2/14/02
to

Christophe Rhodes <cs...@cam.ac.uk> writes:

> Marco Antoniotti <mar...@cs.nyu.edu> writes:
>
> > Here is one of my favourite `primes' in conforming CL.
> >
> > (in-package "SETL-USER")
> >
> > (defun primes (max)
> > [n in (range 3 max 2)
> > / (not (exist m in (range 3 (min (1- n) (+ 2 (sqrt n))) 2)
> > / (= (mod n m) 0)))])
>
> I appreciate the point, but I thought that we decided that "conforming
> CL" programmes needed to include their macros and reader-macros to be
> properly conforming... :-)

Come on! Throw me a bone here! :) The IN-PACKAGE is quite a give away

Dorai Sitaram

unread,
Feb 14, 2002, 11:28:00 AM2/14/02
to
In article <ey3aduc...@cley.com>, Tim Bradshaw <t...@cley.com> wrote:
>* Dorai Sitaram wrote:
>
>> I am inclined to agree, but just yesterday a coupla
>> posts here were praising special tools over
>> general tools. That also sounded somewhat agreeable
>> with at the time, except that their argument put CL
>> firmly on the side of the specializers, not
>> generalizers as the above seems to be doing (unless
>> Lisp is not being equated with CL).
>
>If you are referring to the article I wrote where I said I didn't try
>and write general libraries or tools, then that's not quite what I was
>trying to say.
>...

>*But*, since I think that design of general tools is so hard, or at
>least it is hard for me, I tend to not try, but instead to design
>special tools for the job at hand. That way I actually get the job
>done.
>
>So I wasn't making a value judgement, more trying to describe how I
>work.

Actually, I was referring to Thomas [Burdick] and
Kent's articles rather than yours. If it was yours and
I was referring to it in a followup to you yourself,
let me assure you that I would find it weird to
third-person it so. :-)

--d

Pierre R. Mai

unread,
Feb 14, 2002, 10:38:03 AM2/14/02
to
Marco Antoniotti <mar...@cs.nyu.edu> writes:

> Ed L Cashin <eca...@uga.edu> writes:
>
> > Also, I remember thinking that lisp looked like "text vomit" compared
> > to languages whose structure lexically mirrors what's going on.
> > Here's an example in ruby:
> >
> > {
> > "foo" => "bar",
> > "baz" => "burfle",
> > }.each { |i|
> > puts i
> > }
>
> (map* #'print
> (make-hash-table* '(("foo" => "bar")
> ("baz" => "bar"))))

Or, another way:

(maphash (lambda (key value) (format t "~A => ~A~%" key value))
(equal-hash-table "foo" "bar" "baz" "bar"))

The point being that hash-tables (_unlike_ many other data-structures
in CL), lack both reader-syntax and simple creation functions. Thus
the disadvantage when compared to Ruby/Perl/...; but I consider that
accidental, since CL does have such support for things like lists,
vectors, arrays, etc.

Probably make-hash-table should take an initial-contents keyword arg,
just like make-array does, e.g.

(maphash (lambda (key value) (format t "~A => ~A~%" key value))
(make-hash-table :test #'equal
:initial-contents '(("foo" "bar") ("baz" "bar"))))

Regs, Pierre.

--
Pierre R. Mai <pm...@acm.org> http://www.pmsf.de/pmai/
The most likely way for the world to be destroyed, most experts agree,
is by accident. That's where we come in; we're computer professionals.
We cause accidents. -- Nathaniel Borenstein

Brian Campbell

unread,
Feb 14, 2002, 1:37:04 PM2/14/02
to
> Not with me. I have no problem with parentheses, except that I don't
> know all the rules to their use, and I don't want to learn the entire
> common-lisp language to find out; either. I may do so, but I WILL
> find a better way, if I can!

The rules are very simple. Everything in lisp is either an atom or a
list. Atoms are single values; numbers, variables, strings, or a couple
of assorted other things that you won't need to use that much. If you
want something more complex than one of those (like, applying a function
to some arguments), you need a list. Lists are delimited by parentheses,
and their first element is the function you are calling or the special
form you are using (I'll get to the difference between functions and
special forms later). So if you want to add 4 and 5, you use the +
function (yes, in lisp + is a function like any other, it's not some
special operator), you write:

(+ 4 5)
=> 9

It's as simple as that! Here are some more examples. Say I want to add 4
to the result of multiplying 5 by 2. Starting from the outside, I write:

(+ 4 ...)

This applies the function plus the the argument 4 and the result of the
multiplication (represented here as ...). Now how do you do the
multiplication? Exactly the same way you did the addition:

(+ 4 (* 5 2))
=> 14

All function application works exactly this way. The interpreter or
compiler executes code by evaluating it. Evaluation for an number or
string returns that number or string:

4
=> 4

"foo"
=> "foo"

Evaluation of a symbol which refers to a variable returns the value of
that variable:

;; x has been set or bound before to 5
x
=> 5

Evaluation of a list (which is a function application) evaluates every
element of the list (I'm simplifying a little bit here, and using the
semantics of Scheme, rather than Common Lisp, because it makes more
sense that way), and then applies the function which appears at the
beginning to the (evaluated) rest of the arguments (I will use < and >
to enclose the evalueated value of the elements of the list):

(+ 4 (* 5 2))
(<function:+> <number:4> ...)
(<function:*> <number:5> <number:2>) => 10
(<function:+> <number:4> <number:10>) => 14
=> 14

The difference between a function and a special form is that in a
special form, it doesn't go through and evaluate every element. Instead,
it looks at the first one, and based on that decides how to evaluate the
rest. For example, when you are using if, you don't want it to evaluate
both the true and false conditions. For example, if you're writing
something that controls a nuclear weapon launch (this example stolen
from SICP), you don't want the statement

(if (at-war? us)
(launch missile)
(keep-waiting))

to launch the missile every time the if is evaluated!

So you see, parentheses in lisp are actually much simpler than those in
other languages. In C, you need to learn about precedence rules, square
brackets, curly braces, and all kinds of other delimeters, and
parentheses are used for three different things (typecasting, function
calls, and grouping arithmetic statements), while in lisp they are only
used for function calls and special forms.

If you don't want to learn all of Common Lisp, I would recommend Scheme,
which is much conceptually simpler than Common Lisp, but works in the
same basic way. There are some good intros online; go to
<http://www.schemers.org/>. Especially good is Abelson and Sussman, and
Sussman's "Structure and Interpretation of Computer Programs" at
http://mitpress.mit.edu/sicp/full-text/book/book.html (the link is kind
of buried if you try to find it on schemers.org).

(apologies for presenting scheme and advocating scheme on
comp.lang.lisp, but I think that it's better to introduce someone who
doesn't understand all those parentheses to scheme, rather than common
lisp, where you don't evaluate every element of the list uniformly)

--
Brian Campbell
Real email: lambda (at) cs (dot) dartmouth (dot) edu

Daniel Barlow

unread,
Feb 14, 2002, 2:48:56 PM2/14/02
to
Brian Campbell <lambd...@yahoo.com> writes:

> The rules are very simple. Everything in lisp is either an atom or a
> list. Atoms are single values; numbers, variables, strings, or a couple
> of assorted other things that you won't need to use that much. If you

The first sentence is true.

As by definition an atom is anything that is not a cons, then insofar
as the second sentence is true, it's trivially true.

This gives us problems with the third sentence, as atoms thus include
things like packages, arrays, hash tables, and CLOS instances, which I
hope you will agree are generally _not_ "things that you won't need to
use that much"...

If in the second sentence you had instead said "Everything in lisp
_code_ is either an atom or a list", you could have made a rather more
defensible (if still not entirely justified) claim on the third
sentence, because code doesn't often contain literal hash tables.

OK, maybe I'm nit-picking, but confusing lisp code syntax with sexpr
syntax, and confusing the outward sexpr-based representation with the
actual objects are both common new-user mistakes, and I think it helps
to be exact with terminology when explaining.


-dan

--

http://ww.telent.net/cliki/ - Link farm for free CL-on-Unix resources

Wade Humeniuk

unread,
Feb 14, 2002, 7:42:07 PM2/14/02
to
>
> Probably make-hash-table should take an initial-contents keyword arg,
> just like make-array does, e.g.
>
> (maphash (lambda (key value) (format t "~A => ~A~%" key value))
> (make-hash-table :test #'equal
> :initial-contents '(("foo" "bar") ("baz"
"bar"))))

I think hash-tables are meant to store larger amounts of unordered data and
I cannot see using the :initial-contents to populate a 1000+ key/value pairs
(or for that matter 100,000 values). I would rebel at doing the typing.
For me, storing 2 key/value or even 100 values in a hash table is just not
worth it.

Wade


Brian Campbell

unread,
Feb 14, 2002, 7:31:37 PM2/14/02
to
In article <873d033...@noetbook.telent.net>,
Daniel Barlow <d...@telent.net> wrote:

> Brian Campbell <lambd...@yahoo.com> writes:
>
> > The rules are very simple. Everything in lisp is either an atom or a
> > list. Atoms are single values; numbers, variables, strings, or a couple
> > of assorted other things that you won't need to use that much. If you
>
> The first sentence is true.
>
> As by definition an atom is anything that is not a cons, then insofar
> as the second sentence is true, it's trivially true.

I need to define my terms. As the person I was explaing to doesn't
understand what all of the parentheses are for, I needed to make sure he
understood what atoms and lists were.

>
> This gives us problems with the third sentence, as atoms thus include
> things like packages, arrays, hash tables, and CLOS instances, which I
> hope you will agree are generally _not_ "things that you won't need to
> use that much"...

Do you see them literally in the code? It was the syntax, and how that
translated to the semantics, that I was explaining, not the actual set
of values that lisp can represent as data. Perhaps I should have been
more specific; rather than "everything in lisp", I should have said
"every expression in lisp". Besides numbers, symbols (which I called
variables here to draw the parallel with other programming languages),
strings, and lists, there's not much else that you see in the code.
There are vectors, and quoted symbols and lists, and a few other kinds
of atoms that can appear in the syntax, but as you said, you don't often
see literal hash tables. Also, since I was recommending he look into
Scheme if he didn't want to learn all of Common Lisp, I didn't want to
confuse him with things that were different between them; should I have
mentioned t and nil, or #t and #f? Should I have mentioned arrays, or
just vectors? As the atoms that I mentioned are common between both
scheme and common lisp, and make up 90% or more of the syntax that you
see, I decided to only include them.

>
> If in the second sentence you had instead said "Everything in lisp
> _code_ is either an atom or a list", you could have made a rather more
> defensible (if still not entirely justified) claim on the third
> sentence, because code doesn't often contain literal hash tables.
>
> OK, maybe I'm nit-picking, but confusing lisp code syntax with sexpr
> syntax, and confusing the outward sexpr-based representation with the
> actual objects are both common new-user mistakes, and I think it helps
> to be exact with terminology when explaining.

Yes, I was sloppy. I think that coming from the perspective of the
person I was writing for, it would still clear matters up more than it
would confuse him. Anyhow, both lisp syntax and sexpr syntax are the
syntax that can be parsed by the read function. There are additional
constraints on the lisp code, it is true, but lisp code is a use of
sexpressions for representing a program, and confusing the syntax with
the actual objects is a mistake, but that is why, when demonstrating
evaluation, I made sure to use a notation that distinguished objects
from their representation.

>
>
> -dan

Pierre R. Mai

unread,
Feb 14, 2002, 8:41:51 PM2/14/02
to
"Wade Humeniuk" <hume...@cadvision.com> writes:

The value for the initial-contents argument can be arrived at in any
way wanted. It is not limited to being a literal. Furthermore, in is
quite conceivable that the hash-table in question is going to grow to
many values (thereby validating the use of a hash-table), yet is
seeded with a smallish amount of initial-contents, where the typing
isn't problematic. And then there are many cases where you want to
interactively test a function that is specified to work on
hash-tables, where a few entries in the table suffices.

It is for those reasons that I think an initial-contents argument to
make-hash-table makes as much sense as it does for make-array. Of
course this is not something I'm going to fret about, but I've more
than once written a "make-hash-table-from-kv-pairs"-type function, and
wouldn't consider such an addition without some good will.

Of course your implicit point that alists are often a better choice
(which accidentally also have good support for literal input) for
smallish lookup tables is duly taken.

Gareth McCaughan

unread,
Feb 14, 2002, 9:04:51 PM2/14/02
to
Tim Bradshaw wrote:

> * Erik Naggum wrote:
>
> > It appears warranted by the various reactions people have posted and told
> > of elsewhere to conclude that Common Lisp is a language that is better
> > suited for those who are more verbal than visual in how they remember and
> > learn. Those who are more visual, tend to be thrown off by the lack of
> > visual clues and the preponderance of words they need to recognize in
> > order to "see" the structure. The verbal, who recognize words the way
> > the visual see pictures and figures, have no such problem.
>
> I think this is an interesting point. However I'm not sure it's right
> or at least not uniquely right. I think I'm a terribly visual person
> (although I also can read).

[etc]

Whereas I'm a visually terrible person :-), so according to Erik's
criterion it makes sense that I like Lisp; but I also find visual
tricks like syntax-colouring extremely helpful, in Lisp and also in
other languages. (Maybe I find those tricks helpful *because* I'm
not very visual; perhaps if my visual subsystem worked better it
would do those jobs unaided.)

And, despite being very "verbal", I do find that sometimes the
"verbosity" of Lisp bothers me. I don't think I've yet found an
instance where it's (1) genuine verbosity and (2) not easily
fixed with a bit of macrology or read-table manipulation; but
it can still cause discomfort. It's possible that the discomfort
is a useful signal that macrology might be in order.

*

Example: Earlier in the thread, someone posted a comparison between
two code snippets, one in Ruby and one in Lisp. Both had the form:
build a hash table containing known keys and values, then iterate
over it. The Ruby code was shorter and allegedly clearer. (I find
the ambiguous use of curly brackets in Ruby disagreeable, but never
mind that.) And it's true: the CL code is verbose and hard to read.

But, if you're doing a lot of that sort of thing then it's the work
of a minute (well, OK, five minutes) to write two simple macros so
you can write

(dohash (key value)
(hash ("foo" "bar") ("baz" "quux"))
(format t "~&~A -> ~A.~%" key value))

which seems to me just as clear (to someone with a little Lisp
experience; no one denies that Lisp takes getting used to) as

{"foo" => "bar", "baz" => "quux"}.each {
|key, value|
print key, " -> ", value, "\n"
}

or, for that matter,

for key,value in {"foo": "bar", "baz": "quux"}.items():
print key, "->", value, "\n"

except that FORMAT looks too much like line noise to some readers.
(Compression implies near-randomness.) Again, if you do a lot of
writing sequences of things to *STANDARD-OUTPUT* then it's the
work of another minute or two to write a function so you can say

(dohash (key value)
(hash ("foo" "bar") ("baz" "quux"))
(output key " -> " value #\Newline))

Ruby and Python and all sorts of other languages have advantages
over CL, but brevity and clarity aren't among them unless either
your programs are so short that brevity and clarity don't matter
anyway, or you're deliberately choosing to write CL in a way that
doesn't provide the sort of brevity and clarity you want.

*

(defvar *preferred-hash-test* 'equal)

(defmacro hash (&rest pairs)
(let ((result (gensym)))
`(let ((,result (make-hash-table :test ',*preferred-hash-test*)))
,@(loop for (key value) in pairs collect
`(setf (gethash ,key ,result) ,value))
,result)))

(defmacro dohash ((k v) hform &body body)
`(loop for ,k being each hash-key of ,hform using (hash-value ,v) do
. ,body))

(defun output (&rest values)
(loop for value in values do (princ value)))

--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc

zaphod

unread,
Feb 14, 2002, 11:50:46 PM2/14/02
to
Erik Naggum <er...@naggum.net> wrote in message news:<32226813...@naggum.net>...

> * Sla...@ureach.com (zaphod)
> | Not with me. I have no problem with parentheses, except that I don't
> | know all the rules to their use, and I don't want to learn the entire
> | common-lisp language to find out; either. I may do so, but I WILL
> | find a better way, if I can!
>
> Quite amazing. It is obviously superfluous to answer any of your
> questions with technical answers. This is good to know.

Yapp; reckon I'm an illiterat know knothing cluck; or maby you don't
know enough about me and my situation to know much at all about me or
my situation (look Ma; recursion). Sorry about my inadequacies. If I
put my attention purely on learning Common Lisp, I might surprise
someone with my astuteness as a student, then again; I might not. I
just wanted to let you know, that it's not neccasarilly an IRRATIONAL
dislike of parens. There just might be some rationality behind it.
In my case; I gave it a try, and discovered it wasn't as easy as I've
been lead to beleive, but I'm so dang low-brow, I hack trial and
error, when it seems right. I should have prefaced all with.
Me=newbie know-nothing, tho.
>
> ///

Erik Naggum

unread,
Feb 15, 2002, 2:37:45 AM2/15/02
to
* "Wade Humeniuk" <hume...@cadvision.com>

| I think hash-tables are meant to store larger amounts of unordered data and
| I cannot see using the :initial-contents to populate a 1000+ key/value pairs
| (or for that matter 100,000 values). I would rebel at doing the typing.
| For me, storing 2 key/value or even 100 values in a hash table is just not
| worth it.

When a hash-table is all you have, you tend to optimize it heavily. The
same goes for regexps. Both hash-tables and regular expressions are very
powerful and general tools, but they turn into monstrosities when all the
more specialized tools are effectively removed from the language they use.

Common Lisp has the disadvantage compared to the one-trick languages that
the different access functions for various kinds of mappings between key
and value are precisely that -- different. When there is only one way to
do it, being offered several ways is just confusing, and so people who
think "hash-table" when they should have thought "key-value mapping" will
miss simple and elegant things like property lists or association lists.

I mean, if { "foo" => "bar", "baz" => "zot" } is so great, why is not
(("foo" . "bar") ("baz" . "zot"))? Is it _only_ the sugar-coated syntax
that is so visually appealing to some? If so, a Common Lisp programmer
will write a small parser function that is called via the reader-macro
support to read this list. Why is this not more used? I belive it is
because most people who pine for other syntaxes have no clue how to go
about specifying them or writing parsers for them, and because once you
have grown that clue, you do not need it or, more importantly, want it.

But what the heck. Proof of concept follows.

(let ((mapping-types ()))
(defun readtable-mapping-type (readtable)
(check-type readtable readtable)
(or (cdr (assoc readtable mapping-types)) :alist))

(defun (setf readtable-mapping-type) (mode readtable)
(check-type readtable readtable)
(check-type mode (member :alist :plist :eq :eql :equal :equalp))
(let ((existing (assoc readtable mapping-types)))
(if existing
(setf (cdr existing) mode)
(push (cons readtable mode) mapping-types))))

(defun mapping-reader (stream char)
(declare (stream stream) (ignore char))
(loop
with mapping-type = (readtable-mapping-type *readtable*)
with key and value
with hashtable = (case mapping-type
(:eq (make-hash-table :test #'eq))
(:eql (make-hash-table :test #'eql))
(:equal (make-hash-table :test #'equal))
(:equalp (make-hash-table :test #'equalp)))
do
(when (eql #\} (peek-char t stream t nil t))
(read-char stream t nil t)
(loop-finish))
(setq key (read stream t nil t))
(if (eql #\= (peek-char t stream t nil t))
(read-char stream t nil t)
(error 'parse-error :stream stream))
(unless (eql #\> (read-char stream t nil t))
(error 'parse-error :stream stream))
(setq value (read stream t nil t))
(case (peek-char t stream t nil t)
(#\, (read-char stream t nil t))
(#\} t)
(t (error 'parse-error :stream stream)))
if (eq mapping-type :alist) collect (cons key value) into list else
if (eq mapping-type :plist) collect key into list
and collect value into list else
do (setf (gethash key hashtable) value)
finally (case mapping-type
((:alist :plist) (return (list 'quote list)))
(t (return hashtable))))))

Now, suppose the above is available in the Common Lisp world. A file
that uses this syntax could go like this:

(eval-when (:execute :compile-toplevel)
(setq *readtable* (copy-readtable))
(set-macro-character #\{ #'mapping-reader)
(set-syntax-from-char #\} #\)))

(eval-when (:execute :compile-toplevel)
(setf (readtable-mapping-type *readtable*) :alist))

(defparameter *roman-alist*
{ "I" => 1,
"V" => 5,
"X" => 10,
"L" => 50,
"C" => 100,
"D" => 500,
"M" => 1000 })

(eval-when (:execute :compile-toplevel)
(setf (readtable-mapping-type *readtable*) :plist))

(defparameter *roman-plist*
{ "I" => 1,
"V" => 5,
"X" => 10,
"L" => 50,
"C" => 100,
"D" => 500,
"M" => 1000 })

(eval-when (:execute :compile-toplevel)
(setf (readtable-mapping-type *readtable*) :equal))

(defparameter *roman-hash*
{ "I" => 1,
"V" => 5,
"X" => 10,
"L" => 50,
"C" => 100,
"D" => 500,
"M" => 1000 })

I chose this design because I figured that it would be annoying to change
the data if the access functions would need to change and that it would
be more convenient to specify this via a readtable-local setting than add
a lot more syntax for it. If you have support for the in-syntaax form
and named readtables, creating a named readtable to invoke this syntax
would obviously be the best solution.

Now, if you want other kinds of things to go on within { }, it is not a
lot of trouble to build a parser by hand, provided you are not a moron
and create syntaxes the like of C++ or some other horrible monstrosity.

Creating a writer for alists, plists, and hashtables that write data in
this syntax is left as an exercise for the reader.

Copyright notice: Copyright © 2002 Erik Naggum. The code may be used to
create commercial products without charge or other license provided that
the author is credited in each source file that uses it or the syntax it
allows. Creation of derivative works is permitted under two conditions:
No rewrites to use if* or not to use loop are allowed, and the author
must be notified by e-mail at <er...@naggum.net>. Search engines are
permitted to index and retrieve this article in perpetuity and present to
users in either normal text or html-ized form, but no other form of re-
publication is permitted. Inclusion of this material in some "cookbook"
is expressly not permitted.

Erik Naggum

unread,
Feb 15, 2002, 2:45:52 AM2/15/02
to
* Brian Campbell <lambd...@yahoo.com>

| The rules are very simple.

Yeah. They go like this:

Rule #1: Don't feed the trolls.

Rule #2: Don't give the trolls the benefit of the doubt.

Rule #3: Don't let the trolls feed on you.

Rule #4: Sufficiently advanced ignorance is indistinguishable from trolls.

Rule #5: Get paid to write books for dummies and permanent newbies.

Erik Naggum

unread,
Feb 15, 2002, 3:05:28 AM2/15/02
to
* Sla...@ureach.com (zaphod)

| I just wanted to let you know, that it's not neccasarilly an IRRATIONAL
| dislike of parens.

You failed.

Kenny Tilton

unread,
Feb 15, 2002, 1:57:57 PM2/15/02
to

zaphod wrote:

> In my case; I gave [parentheses] a try, and discovered it wasn't as easy as I've


> been lead to beleive, but I'm so dang low-brow, I hack trial and
> error, when it seems right.

just curious: how long did you try? Did you have a nice
parentheses-matching editor to help?

thx

--

kenny tilton
clinisys, inc
---------------------------------------------------------------
"We have a pond and a pool. The pond would be good for you."
- Ty to Carl, Caddy Shack

Erann Gat

unread,
Feb 15, 2002, 2:56:24 PM2/15/02
to
In article <32227474...@naggum.net>, Erik Naggum <er...@naggum.net> wrote:

> Common Lisp has the disadvantage compared to the one-trick languages that
> the different access functions for various kinds of mappings between key
> and value are precisely that -- different.

...

> I mean, if { "foo" => "bar", "baz" => "zot" } is so great, why is not
> (("foo" . "bar") ("baz" . "zot"))? Is it _only_ the sugar-coated syntax
> that is so visually appealing to some?

I can't speak for anyone else of course, but what bothers me about alists
is not the syntax but exactly what you said in the first parahraph I
quoted: that the access functions for alists and other kinds of
associative maps are different. You say it's a disadvantage, and I
agree. It is a disadvantage because it tends to steer programmers towards
premature commitment to a particular implementation, and also towards
breaking abstractions (like pushing and popping things onto alists).

I would much prefer to simply specify that I want an associative map
without having to commit myself to a particular underlying
implementation. (Actually, associative maps are an important enough
abstraction that I think it's not unreasonable to think about taking the
decision away from the programmer and having the compiler or the runtime
system choose the implementation automatically.)

> But what the heck. Proof of concept follows.

[snip]

This is the right idea, but you need to add something like the ref macro
to complete the picture. By the time you've done that IMO you've done
enough work on a common enough problem that it's worth talking about
standardizing the interface and building it into implementations so
compilers can be smarter about optimizing it.

E.

Nils Goesche

unread,
Feb 15, 2002, 5:04:58 PM2/15/02
to
In article <gat-150202...@eglaptop.jpl.nasa.gov>, Erann Gat wrote:
> I can't speak for anyone else of course, but what bothers me about alists
> is not the syntax but exactly what you said in the first parahraph I
> quoted: that the access functions for alists and other kinds of
> associative maps are different. You say it's a disadvantage, and I
> agree. It is a disadvantage because it tends to steer programmers towards
> premature commitment to a particular implementation, and also towards
> breaking abstractions (like pushing and popping things onto alists).
>
> I would much prefer to simply specify that I want an associative map
> without having to commit myself to a particular underlying
> implementation. (Actually, associative maps are an important enough
> abstraction that I think it's not unreasonable to think about taking the
> decision away from the programmer and having the compiler or the runtime
> system choose the implementation automatically.)

But when there is no difference whatsoever in usage interface of
assoc lists or hash tables, why would we want to use assoc lists in
the first place? I always thought that the main advantage of assoc
lists is that you have all those nice list functions for operating
on them in addition to the boring gethash, and can share data in
sublists if you operate functionally on them.

Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9

Raymond Toy

unread,
Feb 15, 2002, 6:16:06 PM2/15/02
to
>>>>> "Erik" == Erik Naggum <er...@naggum.net> writes:

Erik> Copyright notice: Copyright © 2002 Erik Naggum. The code may be used to
Erik> create commercial products without charge or other license provided that
Erik> the author is credited in each source file that uses it or the syntax it
Erik> allows. Creation of derivative works is permitted under two conditions:
Erik> No rewrites to use if* or not to use loop are allowed, and the author

I don't quite follow the wording here. I think you're saying that any
of the following is forbidden:

1. rewrite this to use if*
2. rewrite this not to use loop

Right?

Ray

Erann Gat

unread,
Feb 15, 2002, 9:48:16 PM2/15/02
to
In article <a4k0ma$srct$1...@ID-125440.news.dfncis.de>, Nils Goesche
<car...@cartan.de> wrote:

I'm not 100% clear on what you're trying to say here, so I'm going to give
a couple of answers and hope a few of them are on-point.

1. Alists can be more efficient than hash tables, particularly for small
data sets.

2. Having "all those nice list functions" is only an advantage insofar as
they let you do something useful. Being able to operate on an alist as a
list is not in and of itself a feature, and can lead to problems if you're
not careful. I can't offhand think of anything useful you can do with an
alist that is fundamentally more difficult with a hashmap.

(Hashmaps, by the way, are one of Common Lisp's best kept secrets, one of
those "other" data types that doesn't get much attention among all the
hoopla over lists, atoms, and symbols. Hashmaps are tremendously useful,
and for a long time Common Lisp was the only language that had them.
Today C is about the only language in common use that doesn't have them.)

3. I don't understand the phrase "in addition to the boring gethash."
Gethash works only on hash tables, not on alists. To do the equivalent of
"gethash" on an alist you have to do (cdr (assoc ... more or less. I
also don't see why gethash is particularly more boring than any other
function.

4. Values stored in hash tables can share structure just as values stored
in alists can.

Was that anywhere near the mark?

E.

Nils Goesche

unread,
Feb 15, 2002, 10:42:00 PM2/15/02
to
In article <gat-150202...@192.168.1.50>, Erann Gat wrote:
> In article <a4k0ma$srct$1...@ID-125440.news.dfncis.de>, Nils Goesche
><car...@cartan.de> wrote:
>
>> In article <gat-150202...@eglaptop.jpl.nasa.gov>, Erann Gat wrote:
>> > I can't speak for anyone else of course, but what bothers me about alists
>> > is not the syntax but exactly what you said in the first parahraph I
>> > quoted: that the access functions for alists and other kinds of
>> > associative maps are different.

[snip]

>> But when there is no difference whatsoever in usage interface of
>> assoc lists or hash tables, why would we want to use assoc lists in
>> the first place?

[snip]

> I'm not 100% clear on what you're trying to say here, so I'm going to give
> a couple of answers and hope a few of them are on-point.

[snip]

> Was that anywhere near the mark?

Yes, absolutely, thank you. I misunderstood you. I thought you were
saying that you didn't like having to use `gethash' in one case and
cdr and assoc in the other case etc. because you wanted to be able
to change your program quickly to use one instead of the other. I
thought that in order to do that you would have to restrict yourself
to use only the common subset of interface both structures have. As
I /still/ think that alists are a more luxurious thing than hash
tables, for the programmer at least, I wouldn't want to restrict
myself to that common subset. But then, maybe I am still
misunderstanding you :-)

Regards,
--
Nils Goesche
Ask not for whom the <CONTROL-G> tolls.

PGP key ID 0xC66D6E6F

Erann Gat

unread,
Feb 15, 2002, 11:18:34 PM2/15/02
to
In article <a4kke8$gng$04$1...@news.t-online.com>, Nils Goesche
<car...@t-online.de> wrote:

> In article <gat-150202...@192.168.1.50>, Erann Gat wrote:
> > In article <a4k0ma$srct$1...@ID-125440.news.dfncis.de>, Nils Goesche
> ><car...@cartan.de> wrote:
> >
> >> In article <gat-150202...@eglaptop.jpl.nasa.gov>, Erann Gat wrote:
> >> > I can't speak for anyone else of course, but what bothers me about alists
> >> > is not the syntax but exactly what you said in the first parahraph I
> >> > quoted: that the access functions for alists and other kinds of
> >> > associative maps are different.
>
> [snip]
>
> >> But when there is no difference whatsoever in usage interface of
> >> assoc lists or hash tables, why would we want to use assoc lists in
> >> the first place?
>
> [snip]
>
> > I'm not 100% clear on what you're trying to say here, so I'm going to give
> > a couple of answers and hope a few of them are on-point.
>
> [snip]
>
> > Was that anywhere near the mark?
>
> Yes, absolutely, thank you. I misunderstood you. I thought you were
> saying that you didn't like having to use `gethash' in one case and
> cdr and assoc in the other case etc. because you wanted to be able
> to change your program quickly to use one instead of the other.

Yes, that is in fact what I was saying.

> I thought that in order to do that you would have to restrict yourself
> to use only the common subset of interface both structures have.

No, that is not what I was saying. Alists and hash tables have no common
subset in their interface. That's the problem. Erik's code solves half
of the problem. The 'ref' macro (discussed in another thread here a few
weeks ago) solves the other half. I'd like to see something like that
standardized.

> As
> I /still/ think that alists are a more luxurious thing than hash
> tables, for the programmer at least, I wouldn't want to restrict
> myself to that common subset.

Since the common subset is empty that would be a severe restriction. But
I'm curious: what is it about alists that you find "luxurious"?

E.

Erik Naggum

unread,
Feb 16, 2002, 1:06:26 AM2/16/02
to
* g...@jpl.nasa.gov (Erann Gat)

| 2. Having "all those nice list functions" is only an advantage insofar as
| they let you do something useful. Being able to operate on an alist as a
| list is not in and of itself a feature, and can lead to problems if you're
| not careful. I can't offhand think of anything useful you can do with an
| alist that is fundamentally more difficult with a hashmap.

Suppose it is a special variable. (let ((*alist* *alist*)) ...) allows
you to push key-value pairs on the list and have them work in a manner
very similar to scoping. You may temporarily push a single key-value
element to shadow another and then delete it when you are done, with a
simple (delete <key> <alist> :key #'car).

Alists are also just as efficient from key to value as from value to key.

Kent M Pitman

unread,
Feb 16, 2002, 1:29:06 AM2/16/02
to
Erik Naggum <er...@naggum.net> writes:

> * g...@jpl.nasa.gov (Erann Gat)
> | 2. Having "all those nice list functions" is only an advantage insofar as
> | they let you do something useful. Being able to operate on an alist as a
> | list is not in and of itself a feature, and can lead to problems if you're
> | not careful. I can't offhand think of anything useful you can do with an
> | alist that is fundamentally more difficult with a hashmap.

(I'm reading out of context and assuming hashmap == hash table.)

You never get something for nothing. Everything is a trade-off.

Alists and plists Maintain an ordering. MAPHASH often goes in a very
unintuitive ordering. You may not _want_ an ordering; that's a different
issue. But certainly there is value to be had from those abstractions.
Order can be important both to presentation and to algorithm.

Also, alists and plists don't suffer from rehash problems upon garbage
collection.

And alists and plists are often short and just plain faster than hash tables,
since computing a key for the hash table involves a certain up front cost
that may not really matter. This depends a little on the hash table
implementation, of course. But I think most implementations of hash tables
have a certain degree of this.

> Suppose it is a special variable. (let ((*alist* *alist*)) ...) allows
> you to push key-value pairs on the list and have them work in a manner
> very similar to scoping. You may temporarily push a single key-value
> element to shadow another and then delete it when you are done, with a
> simple (delete <key> <alist> :key #'car).

Does anyone really do this? I have never gotten satisfactory results from
doing DELETE on a list (or alist) that was shared. As soon as I know someone
else is using it I have to worry I'm not maintaining it well for them.
Consider that there are *seriously* obscure "DELETE bugs" waiting if you
do

(setq l1 (list 4 3 2 1))
(setq l2 (cons 5 l1))
(setq l3 (delete 4 l2))
(setq l4 (delete 2 l2))

l4 => (5 3 1)
l3 => (5 3 1)
l2 => (5 3 1)
l1 => (4 3 1)

> Alists are also just as efficient from key to value as from value to key.

Alists don't suffer any more than other list formats from the problem I just
mentioned. I agree they are "as good as" plists, etc.

I prefer plists just because (a) they have better accessors in the language
and (b) they don't get caught up in that "dot problem" of ((a . b)...) vs
((a b)...).

I describe the basic trade-off between alists and plists this way:

alists are private
plists are restartable

That is, ...

If you do (assoc 'x '((a . b) (x . y) (z . 3) (x . m))) you get back
(x . y). If you wanted the (x . m), there is no easy way to "restart"
the search from the prior point; you have to use MEMBER (which breaks
the alist abstraction) to get restartability). _However_, what you do
get with alists is data privacy. If I want to hand you an object you
can SETF in order to update the table, I don't have to expose entries
to you that are irrelevant; if it were a plist, the only location I
could hand you is the tail of the list, which points to other data you
shouldn't have. That is, plists are not very private.

But as to restartability, if you do (get-properties '(a b x y z 3 x m)
'(x)) you get back X, Y, (X Y Z 3 X M). The third value can be used
to continue searching (i.e., to restart); contrast with an alist
lookup, where you get back the entry, which is not something you can
restart.

Nils Goesche

unread,
Feb 16, 2002, 3:41:03 AM2/16/02
to

Hehe :-) I meant the conceptual interfaces. Even if you have some
syntax and functional interface for addressing both of them in the
same way, you would be restricted to /using/ both alists and hashtables
in the same way. Otherwise you would lose the ability to simply
exchange both data structures in your code.

> But I'm curious: what is it about alists that you find "luxurious"?

Erik Naggum and Kent Pitman described that. After I had posted
the article I was angry that I had forgotten to add ``There is no
such thing as a free lunch.'' I am happy to see that Kent Pitman
apparently had the very same association (no pun intended).

Pierre R. Mai

unread,
Feb 16, 2002, 8:38:09 AM2/16/02