Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Q: on hashes and counting

80 views
Skip to first unread message

The Glauber

unread,
Oct 18, 2000, 3:00:00 AM10/18/00
to
Suppose i have a text file and i want to count strings in it. Specifically,
the first 5 characters of each line in this file are a vendor code.
Then i want to ouptut all vendor codes and how many times
they show up in the input.

Here's what i did:
(let ((curv) (vhash (make-hash-table :test 'equal)))
(with-open-file (s "invdat.txt" :direction :input)
; read until end of file
(do ((l (read-line s) (read-line s nil 'eof)))
((eq l 'eof)
(maphash #'(lambda (k v) (format t "~A,~A~%" k v)) vhash))
; get the first 5 characters of each line
(setq curv (subseq l 0 5))
; if already in hash, increment count, else, create hash entry
(if (gethash curv vhash)
(incf (gethash curv vhash))
(setf (gethash curv vhash) 1)) )))

This is all straightforward, except for these lines:
(if (gethash curv vhash)
(incf (gethash curv vhash))
(setf (gethash curv vhash) 1))

What they do is, if there is already an entry in the hash, increment
the count. If there isn't, create one (with count set to 1).

Is this the best way to use a hash? In other words, do i really have to
do the (gethash key hash) twice? It feels wasteful.

In Perl, you do $hash{key}++ and the entry will get "magically" created if
it isn't there. (Of course, the Perl compiler may be doing the
double lookup behind my back).

The Perl version of this program runs a lot faster than the Lisp version
(6 times faster) (I'm using Clisp and AIX), but i'm assuming that
the main problem with the Lisp version is the fact that each line of text
is consed and thrown away to the garbage collector. I'm pretty sure
Perl would reuse the memory in this case.

Anyway, comparing Perl and Lisp is not the point here, i just want
to understand if i'm using the hashes right.

Thanks,

glauber


P.S.: the Perl version is a "one liner":
$c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print "$x,$c{$x}\n"}}
(very obvious, no? :-))
--
Glauber Ribeiro
thegl...@my-deja.com http://www.myvehiclehistoryreport.com
"Opinions stated are my own and not representative of Experian"


Sent via Deja.com http://www.deja.com/
Before you buy.

The Glauber

unread,
Oct 18, 2000, 3:00:00 AM10/18/00
to
I apologize for deja.com mangling both the Lisp and Perl code.
Here's another try:

Lisp:


(let ((curv) (vhash (make-hash-table :test 'equal)))
(with-open-file (s "invdat.txt" :direction :input)
; read until end of file
(do ((l (read-line s) (read-line s nil 'eof)))
((eq l 'eof)
(maphash #'(lambda (k v) (format t "~A,~A~%" k v)) vhash))
; get the first 5 characters of each line
(setq curv (subseq l 0 5))
; if already in hash, increment count, else, create hash entry
(if (gethash curv vhash)
(incf (gethash curv vhash))
(setf (gethash curv vhash) 1)) )))


Perl:


$c{substr($_,0,5)}++;
END { foreach $x (sort keys %c) {print "$x,$c{$x}\n"}}

--

Barry Margolin

unread,
Oct 18, 2000, 3:00:00 AM10/18/00
to
In article <8sl58e$ivq$1...@nnrp1.deja.com>,

The Glauber <thegl...@my-deja.com> wrote:
>Is this the best way to use a hash? In other words, do i really have to
>do the (gethash key hash) twice? It feels wasteful.

GETHASH allows you to specify a default value, so you can do:

(incf (gethash curv vhash 0))

>In Perl, you do $hash{key}++ and the entry will get "magically" created if
>it isn't there. (Of course, the Perl compiler may be doing the
>double lookup behind my back).

Actually, it's doing something more like the above code. If an entry in a
hash table doesn't exist, $hash{key} returns Perl's "undef" value, which
coerces to 0 in a numeric context.

>The Perl version of this program runs a lot faster than the Lisp version
>(6 times faster) (I'm using Clisp and AIX), but i'm assuming that
>the main problem with the Lisp version is the fact that each line of text
>is consed and thrown away to the garbage collector. I'm pretty sure
>Perl would reuse the memory in this case.

Perl is heavily optimized for string processing like this, since that's
primarily what it's used for.

--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Raymond Wiker

unread,
Oct 19, 2000, 1:36:58 AM10/19/00
to
The Glauber <thegl...@my-deja.com> writes:

> This is all straightforward, except for these lines:

> (if (gethash curv vhash)
> (incf (gethash curv vhash))
> (setf (gethash curv vhash) 1))

(incf (gethash curv vhash 0))

--
Raymond Wiker
Raymon...@fast.no

Pierre R. Mai

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
The Glauber <thegl...@my-deja.com> writes:

> Suppose i have a text file and i want to count strings in it. Specifically,
> the first 5 characters of each line in this file are a vendor code.
> Then i want to ouptut all vendor codes and how many times
> they show up in the input.

(with-open-file (stream "invdat.txt")
(loop with count-hash = (make-hash-table :test #'equal)
for line being the lines of stream
for product-code = (subseq line 0 5)
do
(incf (gethash product-code count-hash 0))
finally


(maphash #'(lambda (k v) (format t "~A,~A~%" k v))

count-hash)))

Of course this depends on an new LOOP clause. If you have a LOOP
macro that is based on the MIT LOOP code (e.g. CMU CL, ACL), you can
use the definition at the end of the article...

But to answer your original question: You can use the default value
of gethash to make incf just work on non-existant keys...

> (let ((curv) (vhash (make-hash-table :test 'equal)))
> (with-open-file (s "invdat.txt" :direction :input)
> ; read until end of file
> (do ((l (read-line s) (read-line s nil 'eof)))
> ((eq l 'eof)
> (maphash #'(lambda (k v) (format t "~A,~A~%" k v)) vhash))
> ; get the first 5 characters of each line
> (setq curv (subseq l 0 5))
> ; if already in hash, increment count, else, create hash entry

> (if (gethash curv vhash)
> (incf (gethash curv vhash))

> (setf (gethash curv vhash) 1)) )))

I'd write that as

(with-open-file (s "invdat.txt")
(do ((count-hash (make-hash-table :test #'equal))
(line (read-line s nil nil) (read-line s nil nil)))
((null line)
(maphash #'(lambda (k v) (format t "~A,~A~%" k v)) count-hash))
(let ((product-code (subseq line 0 5)))
(incf (gethash product-code count-hash 0)))))

There are two IMHO important differences between my version and yours:

- Don't ever use setq to set a variable when you can just as well use
let to bind it (setq of curv vs. let of product-code, where the last
one could be folded into the gethash).
- Don't use magic EOF values in places where a simple nil will do just
as well. Magic EOF values are only really required in read&co., not
in read-line.
- Use longer and more precise variable names... Yes, I'm often guilty
of using cryptic names myself... ;)

> The Perl version of this program runs a lot faster than the Lisp version
> (6 times faster) (I'm using Clisp and AIX), but i'm assuming that
> the main problem with the Lisp version is the fact that each line of text
> is consed and thrown away to the garbage collector. I'm pretty sure
> Perl would reuse the memory in this case.

Should this really turn out to be a performance problem (which I
doubt), you could write your own read-line which re-used an internal
buffer, and only returned the first 5 characters.

> P.S.: the Perl version is a "one liner":

> $c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print "$x,$c{$x}\n"}}

> (very obvious, no? :-))

Hmmm, my Perl might be quite rusty (which is a good thing), but you
seem to be missing the open, the while(<STREAM>) and close here, which
would add at least one line ;)

Regs, Pierre.

;;;; This defines a loop path for the lines of a stream.

(in-package :ANSI-LOOP)

;;; Syntax: loop for var being the lines of stream [split-by char]
;;; Syntax: loop for var being each line in stream [split-on char]

(defun loop-lines-iteration-path (variable data-type prep-phrases)
(cond
((cddr prep-phrases)
(loop-error "Too many prepositions!"))
((null prep-phrases)
(loop-error "Missing OF or IN in ~S iteration path."))
((null (cdr prep-phrases))
(unless (member (caar prep-phrases) '(:of :in))
(loop-error "Missing OF or IN in ~S iteration path."))
(unless (symbolp variable)
(loop-error "Destructuring is not valid for line iteration."))
(let ((stream-var (loop-gentemp 'loop-line-)))
`(((,variable nil ,data-type) (,stream-var ,(cadar prep-phrases)))
()
()
()
(not (setq ,variable (read-line ,stream-var nil nil)))
())))
;; We are splitting
((consp variable)
(let ((stream-var (loop-gentemp 'loop-line-))
(by-var (loop-gentemp 'loop-line-by-))
(line-var (loop-gentemp 'loop-line-line-))
(step-var (loop-gentemp 'loop-line-step-)))
`(((,variable nil ,data-type) (,stream-var ,(cadar prep-phrases))
(,by-var ,(cadadr prep-phrases))
(,line-var nil)
(,step-var nil))
()
()
()
(not (when (setq ,line-var (read-line ,stream-var nil nil))
(setq ,step-var (pmlib:partition ,by-var ,line-var
:remove-empty-subseqs t))))
(,variable ,step-var))))
(t
(let ((stream-var (loop-gentemp 'loop-line-))
(by-var (loop-gentemp 'loop-line-by-))
(line-var (loop-gentemp 'loop-line-line-)))
`(((,variable nil ,data-type) (,stream-var ,(cadar prep-phrases))
(,by-var ,(cadadr prep-phrases))
(,line-var nil))
()
()
()
(not (when (setq ,line-var (read-line ,stream-var nil nil))
(setq ,variable (pmlib:partition ,by-var ,line-var
:remove-empty-subseqs t))))
())))))

(add-loop-path '(line lines) 'loop-lines-iteration-path *loop-ansi-universe*
:preposition-groups '((:of :in) (:split-by :split-on))
:inclusive-permitted nil)

;;; This depends on the following partition function in package pmlib:

(in-package :PMLIB)

;;; The following functions are based on the versions by Arthur
;;; Lemmens of the original code by Bernard Pfahringer posted to
;;; comp.lang.lisp. I only renamed and diddled them a bit.

(defun partition (delimiter seq
&key (maximum nil)
(remove-empty-subseqs nil)
(from-end nil)
(start 0)
(end nil)
(test nil test-supplied)
(test-not nil test-not-supplied)
(key nil key-supplied))
"Return a list of subsequences in seq delimited by delimiter.
If :remove-empty-subseqs is true, empty subsequences will be discarded
from the result; otherwise they will be included.
If :maximum is supplied, the result will contain no more than :maximum
possibly empty subsequences. The second result value contains the
unsplit rest of the sequence.
All other keywords work analogously to those for CL:POSITION."

;; DO: Make keep-delimiters include the delimiters in the result(?).
(let ((len (length seq)))
(unless end (setq end len))
;; DO: Find a more efficient way to take care of :from-end T.
(when from-end
(setf seq (reverse seq))
(psetf start (- len end)
end (- len start)))

(loop with other-keys = (nconc (when test-supplied
(list :test test))
(when test-not-supplied
(list :test-not test-not))
(when key-supplied
(list :key key)))
for left = start then (+ right 1)
for right = (min (or (apply #'position delimiter seq
:start left
other-keys)
len)
end)
unless (and (= right left) ; empty-subsequence
remove-empty-subseqs)
if (and maximum (>= nr-elts maximum))
;; We can't take any more. Return now.
return (values subseqs (subseq seq left end))
else
collect (subseq seq left right) into subseqs
and sum 1 into nr-elts
until (= right end)
finally (return (values subseqs (subseq seq right end))))))

--
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

Erik Naggum

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
* The Glauber <thegl...@my-deja.com>

| Suppose i have a text file and i want to count strings in it.
| Specifically, the first 5 characters of each line in this file are a
| vendor code. Then i want to ouptut all vendor codes and how many
| times they show up in the input.

Here's my cut at that task:

(let ((hash (make-hash-table :test #'equal)))
(with-open-file (stream ...file-args...)
(handler-case
(loop
(let ((vendor (read-sequence stream (make-string 5))))
;; skip to end of line and consume
(peek-char #\newline stream)
(read-char stream)
;; real body of loop
(incf (gethash vendor hash 0))))
;; use conditions to simplify error handling
(end-of-file ())))
(dolist (key (sort (hash-table-keys hash) #'string<))
(format t "~A,~A~%" key (gethash key hash))))

| This is all straightforward, except for these lines:

| (if (gethash curv vhash)
| (incf (gethash curv vhash))
| (setf (gethash curv vhash) 1))
|

| What they do is, if there is already an entry in the hash, increment
| the count. If there isn't, create one (with count set to 1).

You have already been informed about the default value to gethash.

| Is this the best way to use a hash? In other words, do i really have to
| do the (gethash key hash) twice? It feels wasteful.

incf does one gethash to get the value and gethash's setf method to
set the value. If this is noticeably slow, you _may_ do better with
something like this:

(let ((entry (gethash vendor hash nil)))
(if entry
(incf (car entry))
(setf (gethash vendor hash) (list 1))))

| In Perl, you do $hash{key}++ and the entry will get "magically"
| created if it isn't there. (Of course, the Perl compiler may be
| doing the double lookup behind my back).

It is not unlikely that Perl, being a joke of a language around
over-powerful regexps and hash tables, has optimized this to death.

| The Perl version of this program runs a lot faster than the Lisp
| version (6 times faster) (I'm using Clisp and AIX), but i'm assuming
| that the main problem with the Lisp version is the fact that each
| line of text is consed and thrown away to the garbage collector.
| I'm pretty sure Perl would reuse the memory in this case.

Did you compile the Lisp code? Perl _always_ runs slower than Lisp
for me. Of course, I don't use a (good) toy Lisp like CLISP, but
Allegro CL, and I generally compile with high optimization settings.

| Anyway, comparing Perl and Lisp is not the point here, i just want
| to understand if i'm using the hashes right.

Why don't you ask whether hashes are right for the problem? If you
have decided to use Perl, regexps and hashes are the right solution
because you don't have anything else, but regexps are the wrong
solution to almost every problem, and hashes may be similar special
optimizations of particular cases.

I have a situation not dissimilar to yours, where I have ticker
codes for various financial instruments, and I found that it paid
off handsomely to use symbols. Some "modern" Lisp books tell us not
to use symbols, for the same reasons you should not use regexps and
hash tables in Perl, apparently: they are so easy to use that misuse
will be hard to combat, but nobody who uses Perl warns about Perl's
insane focus on bad tools -- those who take the warnings seriously
don't use Perl. So although symbold are expensive structures, they
do have enormous benefits language-wise in Lisp, and they should be
used if the alternative is more cumbersome. With symbols, the above
suggested speed-up becomes

(let ((symbol (intern string package)))
(if (boundp symbol)
(incf (symbol-value symbol))
(setf (symbol-value symbol) 1)))



| P.S.: the Perl version is a "one liner":
| $c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print "$x,$c{$x}\n"}}
| (very obvious, no? :-))

Perl looks the way it does because 110-baud Teletypes were once upon
the time the best people had on Unix, and with lousy typers who had
to correct their mistakes all the time, it made sense to abbreviate
everything down to one or two characters. Lisp has a different
heritage, to put it mildly: Better typers, better use of brainpower
than to remember thousands of subtly similar abbreviations, better
terminals. So we aren't as interested in one-liners with compact
syntax, but for people who still live their lives as if all they can
hope for is a 300-baud Teletype, the value of one-liners cannot be
underestimated.

On the other hand, loop constructs that walk through a file line by
line have been posted, as this seems a reasonable thing to do to
some people. People have regexp libraries for string hacking in
Lisp, too, even though the much better solution is to build a parser
that actually returns the stuctured information in the string. It
turns out that it doesn't take longer, in programmer-time, to write
and test a real parser than it does to write and test regexp-based
string hacking at the same quality level, it may in fact take a lot
shorter time, because the quality level in a parser is so readily
determinable, while people stop worrying about the regexp hacks
until it breaks at sufficiently infrequent random times because they
data never was designed to be hacked by regexps.

Of all the languages I have worked with over the past 20 years,
there's only one that stands out as the Wrong Solution to everything
it does, especially what it does well, and that's Perl. Quotably:

If Perl is the solution, you're solving the wrong problem.

#:Erik
--
I agree with everything you say, but I would
attack to death your right to say it.
-- Tom Stoppard

Peter Vaneynde

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
Erik Naggum <er...@naggum.net> writes:

> * The Glauber <thegl...@my-deja.com>


> Here's my cut at that task:
>
> (let ((hash (make-hash-table :test #'equal)))
> (with-open-file (stream ...file-args...)
> (handler-case
> (loop
> (let ((vendor (read-sequence stream (make-string 5))))

(make-string 5) stream
not?


> ;; skip to end of line and consume

...


> (dolist (key (sort (hash-table-keys hash) #'string<))

hash-table-keys is not in the ANSI-spec, nor in ACL5. I guess it's a
new feature of ACL6?

I suppose it's quite a bit faster then:
(loop for key being the hash-keys in hash collect key)
?

> Did you compile the Lisp code? Perl _always_ runs slower than Lisp
> for me. Of course, I don't use a (good) toy Lisp like CLISP, but
> Allegro CL, and I generally compile with high optimization
> settings.

Your solution outruns the Lisp one on this old SPARC here...

> I have a situation not dissimilar to yours, where I have ticker
> codes for various financial instruments, and I found that it paid
> off handsomely to use symbols. Some "modern" Lisp books tell us not

Symbols in hash-tables or using the plists of the symbols? (I'm supposing
you want to store more then one property per symbol of course)

> I agree with everything you say, but I would
> attack to death your right to say it.
> -- Tom Stoppard

I've been dying to ask in what context this was said...

Groetjes, Peter

--
LANT nv/sa, Research Park Haasrode, Interleuvenlaan 15H, B-3001 Leuven
mailto:Peter.V...@lant.be Phone: ++32 16 405140
http://www.lant.be/ Fax: ++32 16 404961

The Glauber

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
Thanks to all who answered. I learned a couple of important things.

Thanks to the folks who pointed to the default value of gethash, that's
exactly what i was looking for (i knew it had to be there!).

Thanks to Erik for an easy solution to the problem of consing the line each
time.

I don't want to get into a LispxPerl discussion. Perl is a nice thing to have
around when you need a quick answer; it processes text very fast, and it's a
good replacement for awk and sed. So i guess if Perl is a Bad Thing, at least
it allows me to avoid other Unix tools, right? :-) Lisp is a much more mature
language, of course, and more maintainable.

Someone asked, and yes, i compiled the CLISP with maximum optimization, and
it still ran 6 times slower than the Perl one-liner. I'm sure (well, almost
sure) this is because of the consing, and that if i implemented E.N.'s
version it would run at least as fast as Perl.

And here's the code as it stands now:

(let ((vhash (make-hash-table :test 'equal)))
(do ((l (read-line *standard-input*)
(read-line *standard-input* nil nil)))
((null l)


(maphash #'(lambda (k v) (format t "~A,~A~%" k v)) vhash))

(incf (gethash (subseq l 0 5) vhash 0)) ) )

By using the default value for gethash i can easily get rid of one variable.
This version is also reading from stdin and writing to stdout. If i run this
again, i'll put together a better way to print the results in sorted order.

I understand this code is still not 100% perfect, but it's as good as i need
it to be now, so don't waste more of your time improving on it (unless you
really want to! :-)).

Thanks again,

glauber

Erik Naggum

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
* Peter Vaneynde <Peter.V...@lant.be>

| Erik Naggum <er...@naggum.net> writes:
|
| > * The Glauber <thegl...@my-deja.com>
| > Here's my cut at that task:
| >
| > (let ((hash (make-hash-table :test #'equal)))
| > (with-open-file (stream ...file-args...)
| > (handler-case
| > (loop
| > (let ((vendor (read-sequence stream (make-string 5))))
| (make-string 5) stream
| not?

Huh? Oh, the argument order. Please be a little more verbose. I
have no idea how that got in there.

| hash-table-keys is not in the ANSI-spec, nor in ACL5. I guess it's a
| new feature of ACL6?

Oops, sorry, it's my own, an internal function that knows how the
hash-table is laid out and does a quick scan through the keys vector
to collect keys.

| I suppose it's quite a bit faster then:
| (loop for key being the hash-keys in hash collect key)
| ?

That's exactly what I would suggest for the portable definition.

The internal function is twice as fast as this loop.

| > Did you compile the Lisp code? Perl _always_ runs slower than Lisp
| > for me. Of course, I don't use a (good) toy Lisp like CLISP, but
| > Allegro CL, and I generally compile with high optimization
| > settings.
|

| Your solution outruns the Lisp one on this old SPARC here...

I hope you meant "Perl", but couldn't bring yourself to type it. :)

| > I have a situation not dissimilar to yours, where I have ticker
| > codes for various financial instruments, and I found that it paid
| > off handsomely to use symbols. Some "modern" Lisp books tell us not
|

| Symbols in hash-tables or using the plists of the symbols? (I'm
| supposing you want to store more then one property per symbol of
| course)

I let the value slot of the symbols hold one of a variety of
objects, according to the type of the financial instrument.

I don't use symbols as the keys in hash-tables, I use strings, but
that's just an accident of history rather than a conscious decision.

| > I agree with everything you say, but I would
| > attack to death your right to say it.
| > -- Tom Stoppard
|

| I've been dying to ask in what context this was said...

:) Actually, I have no idea. Mark Morford picked this one for the
SF Gate Morning Fix one day. I found it hilarious. (He also uses
"If this is not what you expected, please alter your expectations"
in the disclaimer of the Morning Fix, but someone objected so
strongly to my using that as a .signature, I found it worthwhile to
pick another one.)

The Glauber

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
In article <31809600...@naggum.net>,
Erik Naggum <er...@naggum.net> wrote:
> * Peter Vaneynde <Peter.V...@lant.be>
[...]

> | > I agree with everything you say, but I would
> | > attack to death your right to say it.
> | > -- Tom Stoppard
> |
> | I've been dying to ask in what context this was said...
>
> :) Actually, I have no idea. Mark Morford picked this one for the
> SF Gate Morning Fix one day. I found it hilarious. (He also uses
> "If this is not what you expected, please alter your expectations"
> in the disclaimer of the Morning Fix, but someone objected so
> strongly to my using that as a .signature, I found it worthwhile to
> pick another one.)


Bummer. I liked the "expectations" quote better.

The Hitch-hiker's Guide To The Galaxy has a disclaimer that says something
like "in case of discrepancy between what you see here and reality, reality
has got it wrong."

The Glauber

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
In article <bruce-4CCA15....@news.akl.ihug.co.nz>,
Bruce Hoult <br...@hoult.org> wrote:
[...]

> No. You need to actually know and *understand* the fully-spelled-out
> Perl version before the abbreviated version is anything other than a
> magic incantation that you have no choice but to remember by rote. You
> still need the complete thinking process. Perl just lets you save a bit
> on the typing. And not even on that, quite often -- where is the magic
> shortcut incantation to iterate through the sorted keys of a hash,
> instead of having to spell that part out in full?

I agree with everything you said, and won't even attack you for saying it. :-)

(Sorry, i've been reading Erik Naggum.)

(Actually, the part about the Perl code being obvious to the eye was really a
joke.)

The Glauber

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
In article <bruce-4CCA15....@news.akl.ihug.co.nz>,
Bruce Hoult <br...@hoult.org> wrote:
> In article <8sl58e$ivq$1...@nnrp1.deja.com>, The Glauber
> <thegl...@my-deja.com> wrote:
>
> > P.S.: the Perl version is a "one liner":
> > $c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print
> > "$x,$c{$x}\n"}}
>
> No, that's not the complete Perl source code. You forgot to mention the
> command line flags neded to run it, namely "-n", which means that your
> program is really:


It just occurred to me that if you're going to nit-pick things like what
happen when you use -n in the command line, you probably should
also expand all macros in the Lisp code too. Practical languages have
stuff in them to make it easier for you to get the job done. That's why
we have things like with-open-file. Of course any good programmer
with 6 months experience could code that, but why should we have to?

Also, you can do that same program in Lisp as a "one-liner" ... if
you happen to have the right initialization files!

These are just a couple of reasons why this kind of language competition
is not likely to lead to much enlightment. However, i still think that to be
a Good Programmer (whatever this means) one has to be comfortable
with more than one programming language (and i mean comfortable to
the point of writing "idiomatic" code, that is, Lisp code that looks like
Lisp and C code that looks like C). Incidentally, both Perl and TCL
(and probably Python, i haven't used it for a while) borrow heavily
from Lisp.

When i'm looking for programmers to hire, i always try to find the ones
who are comfortable in more than one language, but they are
surprisingly hard to find! There's a lot of "one language wonders"
out there.

I've never seen it put better than it was done by Peter Norvig:
http://www.norvig.com/21-days.html

Wayne Rogers

unread,
Oct 19, 2000, 3:00:00 AM10/19/00
to
Pierre;
I believe he is doing something like

#!/bin/perl -n -e '$c{substr($_,0,5)}++ ...' input_file

processes each line of the file using the execution statements in the -e
directive

Wayne


"Pierre R. Mai" <pm...@acm.org> wrote in message
news:878zrlp...@orion.bln.pmsf.de...

Bruce Hoult

unread,
Oct 19, 2000, 4:51:22 PM10/19/00
to
In article <8sl58e$ivq$1...@nnrp1.deja.com>, The Glauber
<thegl...@my-deja.com> wrote:

> P.S.: the Perl version is a "one liner":
> $c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print
> "$x,$c{$x}\n"}}

No, that's not the complete Perl source code. You forgot to mention the

command line flags neded to run it, namely "-n", which means that your
program is really:

LINE:
while (<>){


$c{substr($_,0,5)}++; END { foreach $x (sort keys %c) {print
"$x,$c{$x}\n"}}
}


Which would be better written as:

while (<>){
$c{substr($_,0,5)}++;
}

foreach $x (sort keys %c) {
print "$x,$c{$x}\n"
}

... which actually means ...

while ($line = <STDIN>){
$c{substr($line,0,5)}++;
}

foreach $x (sort keys %c) {
print "$x,$c{$x}\n"
}

... and in a program you intend to keep and maintain should be ...

#!/usr/bin/perl -w

use strict;

my %c = {};

while (my $line = <STDIN>){
$c{substr($line,0,5)}++;
}

foreach my $x (sort keys %c) {
print "$x,$c{$x}\n"
}


And now we're up to the same size program as it takes to do the same
thing in C++ or Lisp or Dylan or just about anything else with a decent
library of data structures.

Perl isn't really more compact than other languages, it just has more
special-case hack shortcuts that are *sometimes* useful (often even, for
the things Perl is usually used for), but that you'll have to spell out
by hand as soon as you start doing more complex things for which the
defaults aren't *quite* right.


> (very obvious, no? :-))

No. You need to actually know and *understand* the fully-spelled-out
Perl version before the abbreviated version is anything other than a
magic incantation that you have no choice but to remember by rote. You
still need the complete thinking process. Perl just lets you save a bit
on the typing. And not even on that, quite often -- where is the magic
shortcut incantation to iterate through the sorted keys of a hash,
instead of having to spell that part out in full?

-- Bruce

Bruce Hoult

unread,
Oct 19, 2000, 8:57:50 PM10/19/00
to
In article <8snsfg$pre$1...@nnrp1.deja.com>, The Glauber
<thegl...@my-deja.com> wrote:

> It just occurred to me that if you're going to nit-pick things like what
> happen when you use -n in the command line, you probably should
> also expand all macros in the Lisp code too. Practical languages have
> stuff in them to make it easier for you to get the job done. That's why
> we have things like with-open-file. Of course any good programmer
> with 6 months experience could code that, but why should we have to?
>
> Also, you can do that same program in Lisp as a "one-liner" ... if
> you happen to have the right initialization files!

I agree entirely.


> Incidentally, both Perl and TCL (and probably Python, i haven't used
> it for a while) borrow heavily from Lisp.

You think?

sub cons ($$) {
my ($car, $cdr) = @_;
sub ($) {$_ = shift;
/car/ && return $car;
/cdr/ && return $cdr;
}
}

sub car ($){&{$_[0]}(car);}
sub cdr ($){&{$_[0]}(cdr);}

my $x = cons(12, cons(3.1415, cons("hello world!", 78)));
print "the third element is '", car(cdr(cdr($x))), "'\n";
--------------------------------------------------------
the third element is 'hello world!'

> When i'm looking for programmers to hire, i always try to find the ones
> who are comfortable in more than one language, but they are
> surprisingly hard to find! There's a lot of "one language wonders"
> out there.

I usually seem to get told that I "can't be focussed enough" and that
"over here in the US there are so many good people that if you don't
specialize then you can't be a top performer at anything".

-- Bruce

Pierre R. Mai

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
"Wayne Rogers" <way...@erols.com> writes:

> Pierre;
> I believe he is doing something like
>
> #!/bin/perl -n -e '$c{substr($_,0,5)}++ ...' input_file
>
> processes each line of the file using the execution statements in the -e
> directive

Right, I forgot about the nice command-line options that affect
program semantics in Perl. As if it's syntax weren't enough to
confuse people...

OTOH, this will use stdin, whereas the CL code was opening it's own
stream for a named file, so it seems hardly fair comparing the two.

Regs, Pierre.

The Glauber

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
In article <bruce-44A383....@news.akl.ihug.co.nz>,

Bruce Hoult <br...@hoult.org> wrote:
> In article <8snsfg$pre$1...@nnrp1.deja.com>, The Glauber
> <thegl...@my-deja.com> wrote:
[...]

> > When i'm looking for programmers to hire, i always try to find the ones
> > who are comfortable in more than one language, but they are
> > surprisingly hard to find! There's a lot of "one language wonders"
> > out there.
>
> I usually seem to get told that I "can't be focussed enough" and that
> "over here in the US there are so many good people that if you don't
> specialize then you can't be a top performer at anything".


In a sense this is true, like it's true of those people who get Olympic
medals. So, i'll never run 100 m in under 10 seconds, big deal, i can get
there much faster by car! :-)

I think software creation is a multi-discipline activity, and not only you
gain by knowing other programming languages, but you gain by knowing other
fields as well. Programming is solving problems, and solving problems
sometimes requires being able to think outside the box.

Erik Naggum

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
* The Glauber <thegl...@my-deja.com>

| I think software creation is a multi-discipline activity, and not
| only you gain by knowing other programming languages, but you gain
| by knowing other fields as well. Programming is solving problems,
| and solving problems sometimes requires being able to think outside
| the box.

How does this require multiple language skills? Must an author be
able to write great literature in multiple languages?

Put it this way: I hate it when people do reasonably smart stuff in
Perl, because it is just as incomprehensible to me as Umberto Eco's
great stuff in Italian. I'm annoyed by the fact that I have to work
with a translation, especially since I have no idea how good it is,
but I'm not going to call him a "one-language wonder".

The idea that one language cannot be all things to all people is
probably wrong, but the kinds of languages that have tried have been
all things to some people in abject disregard of most other people,
which may lead to the wrong conclusions. Designing a language that
is enabling and not restricting is very, very hard and requires so
much forethought and probably dissociation from one's own goals that
it will most probably grow into being rather than be designed from
the start. However, things that grow fall into two main categories:
weeds and produce. We have two particularly interesting examples of
weeds: Perl and C++. I consider Common Lisp a grown language, too,
as opposed to designed-to-be-everything-for-a-few-people like Scheme.

I fully agree that problem solving is not something you can do
without knowing the problems and their interrelationships with the
rest of the world. However, when most business schools churn out
generic managers, I suppose it will be harder to convince such
people that programmers actually need to understand the issues and
the problems they are facing. The era of designers and coders is
behind us, and all we know is it didn't work very well, but not why.
Perhaps if more of the people who call themselves programmers or
even software engineers these days were labeled coders and had
somebody else think for them, we would need far less of them simply
because they _can't_ think and therefore write so much miserably
buggy code, while the real thinking that goes into modern "apps" is
very sparse, indeed, compared to all the work required in coding, so
it could probably be handled by a relatively tiny group of people.

#:Erik
--

The Glauber

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
In article <31809600...@naggum.net>,
Erik Naggum <er...@naggum.net> wrote:
> * Peter Vaneynde <Peter.V...@lant.be>
> | Erik Naggum <er...@naggum.net> writes:
> |
> | > * The Glauber <thegl...@my-deja.com>
> | > Here's my cut at that task:
> | >
> | > (let ((hash (make-hash-table :test #'equal)))
> | > (with-open-file (stream ...file-args...)
> | > (handler-case
> | > (loop
> | > (let ((vendor (read-sequence stream (make-string 5))))
> | (make-string 5) stream
> | not?
>
> Huh? Oh, the argument order. Please be a little more verbose. I
> have no idea how that got in there.


I still don't understand how this works. read-sequence returns a position,
not a string; "vendor" would be bound to the number 5, right?

> | hash-table-keys is not in the ANSI-spec, nor in ACL5. I guess it's a
> | new feature of ACL6?
>
> Oops, sorry, it's my own, an internal function that knows how the
> hash-table is laid out and does a quick scan through the keys vector
> to collect keys.


Here's my version (probably not very fast, but using only what i know of CL):

;;; Return the hash's keys, in no particular order
;;; NOTE: Don't modify the keys!
(defmacro hash-table-keys (hash)
(let ((key (gensym)) (val (gensym)) (keylist (gensym)))
`(let ((,keylist '()))
(maphash #'(lambda (,key ,val) (push ,key ,keylist)) ,hash)
,keylist
)
)
)

The Glauber

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
In article <31810498...@naggum.net>,

Erik Naggum <er...@naggum.net> wrote:
> * The Glauber <thegl...@my-deja.com>
> | I think software creation is a multi-discipline activity, and not
> | only you gain by knowing other programming languages, but you gain
> | by knowing other fields as well. Programming is solving problems,
> | and solving problems sometimes requires being able to think outside
> | the box.
>
> How does this require multiple language skills? Must an author be
> able to write great literature in multiple languages?

Great example. There's very little empyrical evidence, of course, but i
believe that someone that can write great literature, say, in Russian, would
also write great literature in Portuguese, if he had to.

It helps not in the sense that knowing C will help you write better Lisp, but
in the sense that it opens up the mind to thinking in different ways. Someone
can probably be a great programmer and only know one language, but i prefer
to work with people that are more curious than this.

Whatever it is that makes someone a good programmer is not tied to the choice
of programming language. Most people can learn another computer language
easily. It's the problem solving thinking, the ability to analyse and
integrate, that's so hard.

I'm sure you'd be a great Perl programmer! :-)

[...]

glauber

Boris Schaefer

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
Erik Naggum <er...@naggum.net> writes:

| How does this require multiple language skills? Must an author be
| able to write great literature in multiple languages?

I don't think one has to know multiple languages, but I consider
learning multiple languages rewarding because one usually learns new
concepts together with the new languages. I also believe that
learning new concepts makes better programmers.

The languages are not terribly important, but they are a good source
of inspiration.

--
bo...@uncommon-sense.net - <http://www.uncommon-sense.net/>

Because we don't think about future generations, they will never forget us.
-- Henrik Tikkanen

Barry Margolin

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
In article <8sqa12$p6k$1...@nnrp1.deja.com>,

The Glauber <thegl...@my-deja.com> wrote:
>It helps not in the sense that knowing C will help you write better Lisp, but
>in the sense that it opens up the mind to thinking in different ways. Someone
>can probably be a great programmer and only know one language, but i prefer
>to work with people that are more curious than this.

Conversely, if someone only knows one language, and has trouble learning
other languages, they're probably not a "great programmer". The difficulty
they have in learning those other languages suggests that their thought
processes are wedded to the paradigms embodied in that language, a sort of
tunnel vision.

I probably wouldn't consider using BASIC, APL, or Prolog for any project I
was involved in, but I consider myself enriched as a programmer because I
know a little bit of them (there was a time when I was an expert BASIC
programmer, but the language has evolved quite a bit in the two decades
since then, and it would take me a few days to get up to speed on modern
BASIC).

Dirk Zoller

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
Boris Schaefer wrote:

> I don't think one has to know multiple languages, but I consider
> learning multiple languages rewarding because one usually learns new
> concepts together with the new languages. I also believe that
> learning new concepts makes better programmers.

There has been a direction in philosophy which strongly emphasized
and carefully scrutinized the connection between language and thinking.
These people were so caught by the fact that the only way of expressing
their thoughts was language, that they finally didn't seem to see any
difference between philosophic thought and analysis of how language works.
AFAIR Wittgenstein was one of the first in that school of thought and
he was very influential throughout the first half of the last century.

Seems like many programmers feel alike with respect to their programming
languages.


--
Dirk Zoller Phone: +49-69-50959861
Sol-3 GmbH&Co KG Fax: +49-69-50959859
Niddastrape 98-102 e-mail: d...@sol-3.de
60329 Frankfurt/M
Germany

Tom Breton

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
The Glauber <thegl...@my-deja.com> writes:

>
> Also, you can do that same program in Lisp as a "one-liner" ... if
> you happen to have the right initialization files!

Yes, exactly. All of the "how succintly can language X say *this*?"
challenges come down to library issues. (Except for some very poor
languages that can't even use libraries easily)

--
Tom Breton, http://world.std.com/~tob
Not using "gh" 1997-2000. http://world.std.com/~tob/ugh-free.html
Some vocal people in cll make frequent, hasty personal attacks, but if
you killfile them cll becomes usable.

Erik Naggum

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
* The Glauber <thegl...@my-deja.com>

| I still don't understand how this works. read-sequence returns a position,
| not a string; "vendor" would be bound to the number 5, right?

It doesn't work because I blew it. I have this nifty little Emacs
hack that lets me edit Lisp code in an indirect buffer, but I must
have posted the code I jotted down first and discarded the code that
worked after improvements and testing.

The real code goes like this:

(let ((vendor (make-string 5)))
(read-sequence vendor stream)
...

The return value from read-sequence is discarded because it may be
less than 5 only when the end of the file has been reached, and then
we're going to hit the real end of file in the next read operations,
so testing for zero would have been necessary, but only a waste.

I have long been annoyed that read-sequence returns 0 on end of
file. That kind of braindamaged conflation between a "no can do"
whine (useless return value) and "read past the end of the file"
condition doesn't belong in a programming language, but rather in
some underdesigned little toy operating system like early 1970's
Unix. *sigh*

Thomas A. Russ

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
The Glauber <thegl...@my-deja.com> writes:

> ;;; Return the hash's keys, in no particular order
> ;;; NOTE: Don't modify the keys!
> (defmacro hash-table-keys (hash)
> (let ((key (gensym)) (val (gensym)) (keylist (gensym)))
> `(let ((,keylist '()))
> (maphash #'(lambda (,key ,val) (push ,key ,keylist)) ,hash)
> ,keylist
> )
> )
> )

Any particular reason why this is implemented as a macro? It would seem
that a function would do just as well, and be simpler. Since you are
already doing a maphash, the function call overhead can't be worth
worrying about. [Hmmm, maybe this will spawn another premature
optimization thread??]


--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu

Lieven Marchand

unread,
Oct 20, 2000, 3:00:00 AM10/20/00
to
The Glauber <thegl...@my-deja.com> writes:

> Here's my version (probably not very fast, but using only what i know of CL):
>

> ;;; Return the hash's keys, in no particular order
> ;;; NOTE: Don't modify the keys!
> (defmacro hash-table-keys (hash)
> (let ((key (gensym)) (val (gensym)) (keylist (gensym)))
> `(let ((,keylist '()))
> (maphash #'(lambda (,key ,val) (push ,key ,keylist)) ,hash)
> ,keylist
> )
> )
> )

Why did you make this a macro? It would be a lot simpler as a function
and there is no reason to make it a macro.

I'd do something like

;;; untested
(defun hash-table-keys (hash)
(loop for key being each hash-key of hash
collect key))

--
Lieven Marchand <m...@bewoner.dma.be>
Lambda calculus - Call us a mad club

Bruce Hoult

unread,
Oct 20, 2000, 6:38:03 PM10/20/00
to
In article <39F0BF12...@sol-3.de>, Dirk Zoller <d...@sol-3.de>
wrote:

> Boris Schaefer wrote:
>
> > I don't think one has to know multiple languages, but I consider
> > learning multiple languages rewarding because one usually learns new
> > concepts together with the new languages. I also believe that
> > learning new concepts makes better programmers.
>
> There has been a direction in philosophy which strongly emphasized
> and carefully scrutinized the connection between language and thinking.
> These people were so caught by the fact that the only way of expressing
> their thoughts was language, that they finally didn't seem to see any
> difference between philosophic thought and analysis of how language works.
> AFAIR Wittgenstein was one of the first in that school of thought and
> he was very influential throughout the first half of the last century.
>
> Seems like many programmers feel alike with respect to their programming
> languages.

Yeah, I've heard of those guys. Some sort of hypothesis or other,
wasn't there. And isn't that the same school that says things such as
"Specifications are for the weak and timid!" and "What is this talk of
'release'? We do not make software 'releases'. Our software escapes,
leaving a bloody trail of designers and quality assurance people in its
wake!".

Starts with "W", I think :-)

-- Bruce
Conflations R Us

Erik Naggum

unread,
Oct 20, 2000, 8:02:26 PM10/20/00
to
* Barry Margolin <bar...@genuity.net>

| Conversely, if someone only knows one language, and has trouble
| learning other languages, they're probably not a "great programmer".
| The difficulty they have in learning those other languages suggests
| that their thought processes are wedded to the paradigms embodied in
| that language, a sort of tunnel vision.

Well, this is obviously true, but it cuts both ways. Suppose you
are used to several _great_ languages and are asked to work in some
braindamaged language designed by someone whose design concepts
never got out of the 50's, how well could you do it? I have very
serious problems working with C++ for this simple reason: I have
this _overwhelming_ urge to redesign the language first. It is such
a phenomenally moronic _non-design_ anyone with exposure to a real
object-oriented language (such as Simula, on which Bjarne Stroustrup
based his desire to still use C while every other Simula programmer
in the world would have understood that C would be a good language
to implement the machinery needed to build a good Simula system at
best, not a good language in which constantly to reimplement said
machinery by hand) would have to shut off the alarms that go "it's a
trap! run! run!" (add scary movie soundtrack for best effects),
while trying not to think how it would be done in a real language.
Matter of fact, it was a project in C++ (and some class design that
stood the test of time) that caused me to look real hard at doing
something other than programming for a living for the rest of my
life, but then I finally wound up wanting to work with Common Lisp
after having studied several other interesting languages, including
Ada and Smalltalk.

I can't hack Perl, either. My brain starts to yell "This is wrong!
This is all wrong! Don't _do_ this to me!", I lose my concentration
_real_ quick and I start to need caffeine, rest, fresh air, water,
you name it, just about anything other than having to deal with that
Perl shit. I have pissed away _days_ when I was reimplementing some
200-line Perl insanity that used a freaking _database_ to store some
really simple values that would be perfectly happy just sitting in
the value slot of a symbol. What _really_ pisses me _off_ with Perl
is that people work so hard doing so terribl little while they think
they have worked very little doing something really nifty. Fools!

Using such inferior languages is like asking a chef who could have
done wonders with any kind of raw materials, to use a dirty kitchen,
a broken refrigerator with food that is about to die a second time,
broken tools, and brownish tap water that tasted of swamp land. His
first task would be to clean up the place. Creating food in there
would be the furthest from his mind. That's how I feel about Perl
and C++. I prefer to call it "good taste", not "tunnel vision".

I don't like rap, either. Call me intolerant.

Erik Naggum

unread,
Oct 20, 2000, 8:08:48 PM10/20/00
to
* Erik Naggum <er...@naggum.net>

| How does this require multiple language skills? Must an author be
| able to write great literature in multiple languages?

* Boris Schaefer <bo...@uncommon-sense.net>


| I don't think one has to know multiple languages, but I consider
| learning multiple languages rewarding because one usually learns new
| concepts together with the new languages. I also believe that
| learning new concepts makes better programmers.
|

| The languages are not terribly important, but they are a good source
| of inspiration.

Let me repeat the question: How does this require multiple language
skills?

Yes, multiple languages have benefits. Are those benefits tied to
multiple languages? I don't think they are. I think they are tied
to curiosity, creativity, never being fully satisfied that you have
found the best solution, and enough humility to listen to others and
their ideas too It would _not_ be a good thing for a programmer to
_have_ to learn multiple languages to be able to use new concepts,
yet that's exactly how I see most new language come into existence:
Some (relative) idiot can't bring himself to implement his concepts
(which may well be brilliant and truly new) in an existing language,
so he goes off discarding everything others spent years building so
he can have his pet concept easily expressed. That's nuts, really.

There are people who have to design their own alphabets or spellings
in order to feel able to express themselves, but I think we label
them "insane" rather than applaud them as "language designers".

Dirk Zoller

unread,
Oct 20, 2000, 8:45:35 PM10/20/00
to
Erik Naggum wrote:

> Yes, multiple languages have benefits. Are those benefits tied to
> multiple languages? I don't think they are. I think they are tied
> to curiosity, creativity, never being fully satisfied that you have
> found the best solution, and enough humility to listen to others and
> their ideas too It would _not_ be a good thing for a programmer to
> _have_ to learn multiple languages to be able to use new concepts,
> yet that's exactly how I see most new language come into existence:
> Some (relative) idiot can't bring himself to implement his concepts
> (which may well be brilliant and truly new) in an existing language,
> so he goes off discarding everything others spent years building so
> he can have his pet concept easily expressed. That's nuts, really.

Following your argumentation would mean that it is only due to "(relative)
idiot"s that we are not still programming in Assembler or FortranIV.

(If you think you're on the safe side as a Lisp user here, you are not.
Since where is the difference between extending and changing a language
and inventing a new one? You must ask yourself why you're not programming
in some ancient Lisp? Due to idiots which were unable to express themselves
in those dialects, obviously.)

It takes some repeated reconsideration and starting over again and again
from scratch while trying to keep the good stuff, get rid of the bad and
invent a few new bits.

Where what's "good" or "bad" or "desirable new stuff" is to a great deal a
matter of taste and therefore in the big picture -- random. Some languages
survive, most die as experiments. Looks like sheer darwinism. Nature has
achieved a lot by such mechanisms.

> There are people who have to design their own alphabets or spellings
> in order to feel able to express themselves, but I think we label
> them "insane" rather than applaud them as "language designers".

People are different. People express themselves in various ways. Some
discuss in newsgroups, others paint, some design programming languages.
People experiment. This does not mean they're insane, nor stupid, nor
incompetent idiots, nor does any other of Naggum's most frequently used
attributes apply.

--
Dirk Zoller
e-mail: d...@onlinehome.de
http://www.dirk-zoller.de

Christopher Browne

unread,
Oct 20, 2000, 10:38:32 PM10/20/00
to
In our last episode (Fri, 20 Oct 2000 20:30:25 GMT),

the artist formerly known as The Glauber said:
>In article <31810498...@naggum.net>,
> Erik Naggum <er...@naggum.net> wrote:
>> * The Glauber <thegl...@my-deja.com>

>> | I think software creation is a multi-discipline activity, and not
>> | only you gain by knowing other programming languages, but you gain
>> | by knowing other fields as well. Programming is solving problems,
>> | and solving problems sometimes requires being able to think outside
>> | the box.
>>
>> How does this require multiple language skills? Must an author be
>> able to write great literature in multiple languages?
>
>Great example. There's very little empyrical evidence, of course, but i
>believe that someone that can write great literature, say, in Russian, would
>also write great literature in Portuguese, if he had to.

Perhaps; perhaps not. The ability to write "great literature"
involves two major things:

1. Having a great story to tell. This part could _potentially_ be
usable in any language.

2. Having the ability to _express_ that story in some particular
language. The fact that I communicate well in English does not
establish that I can do the same in Russian.

"Great literature" requires both components, in substantial measure.

>It helps not in the sense that knowing C will help you write better
>Lisp, but in the sense that it opens up the mind to thinking in
>different ways. Someone can probably be a great programmer and only
>know one language, but i prefer to work with people that are more
>curious than this.

It is useful to know some different "styles" of programming as this
influences the ability to express yourself in whatever language you
use.

An obvious "retort" to this is that if a particular language (oh, say,
Common Lisp?) happens to be sufficiently expressive, there may be
little merit in "opening" your mind by learning some other _minimally_
expressive language.

>Whatever it is that makes someone a good programmer is not tied to
>the choice of programming language. Most people can learn another
>computer language easily. It's the problem solving thinking, the
>ability to analyse and integrate, that's so hard.

As with "Point #1" up above, there's a need to have a Good Story To
Tell. Knowing arcania of whatever language, whether Lisp, Latin, or
Perl, will do NO good if you can't grapple with the problem and don't
have some sort of "mental picture" of how to solve it.

>I'm sure you'd be a great Perl programmer! :-)

Heads will be exploding all over Scandinavia, no doubt...
--
(concatenate 'string "cbbrowne" "@" "acm.org")
<http://www.ntlug.org/~cbbrowne/lisp.html>
Rules of the Evil Overlord #171. "I will not locate a base in a
volcano, cave, or any other location where it would be ridiculously
easy to bypass security by rappelling down from above."
<http://www.eviloverlord.com/>

Christopher Browne

unread,
Oct 20, 2000, 11:25:00 PM10/20/00
to
In our last episode (Sat, 21 Oct 2000 11:38:03 +1300),

the artist formerly known as Bruce Hoult said:
>"What is this talk of 'release'? We do not make software 'releases'.
>Our software escapes, leaving a bloody trail of designers and quality
>assurance people in its wake!".

Oh, my... That's a .signature struggling to get below the "-- "!!!
--
cbbr...@acm.org - <http://www.hex.net/~cbbrowne/>
Rules of the Evil Overlord #190. "If my mad scientist/wizard tells me
he has almost perfected my Superweapon but it still needs more
testing, I will wait for him to complete the tests. No one ever
conquered the world using a beta version."
<http://www.eviloverlord.com/>

Bruce Hoult

unread,
Oct 20, 2000, 11:56:37 PM10/20/00
to
In article <slrn8v22un....@knuth.brownes.org>,
cbbr...@hex.net wrote:

> In our last episode (Sat, 21 Oct 2000 11:38:03 +1300),
> the artist formerly known as Bruce Hoult said:
> >"What is this talk of 'release'? We do not make software 'releases'.
> >Our software escapes, leaving a bloody trail of designers and quality
> >assurance people in its wake!".
>
> Oh, my... That's a .signature struggling to get below the "-- "!!!

It is actually, of course, from a list of "How to tell if one of your
programmers is a Klingon", which can be found in numerous places on the
net. It does bear a striking resemblance to a number of the places I've
worked, although I think it relates more to the management than to the
grunts.

I trust I don't need to explain the punning link between the Whorfian
(or Sapir-Whorf) Hypothesis and Klingons?

-- Bruce

vsync

unread,
Oct 21, 2000, 12:12:22 AM10/21/00
to
cbbr...@news.hex.net (Christopher Browne) writes:

> "Great literature" requires both components, in substantial measure.

Of course, many things that are called "great literature" and studied
in English class have neither, and are viewed as special simply
because they are old. Conversely, something having been written
recently does not diminish its value at all.

--
vsync
http://quadium.net/ - last updated Sat Oct 7 18:53:10 PDT 2000
(cons (cons (car (cons 'c 'r)) (cdr (cons 'a 'o))) ; Orjner
(cons (cons (car (cons 'n 'c)) (cdr (cons nil 's))) nil))

Erik Naggum

unread,
Oct 20, 2000, 9:55:03 PM10/20/00
to
* Dirk Zoller <d...@onlinehome.de>

| Following your argumentation would mean that it is only due to
| "(relative) idiot"s that we are not still programming in Assembler
| or FortranIV.

That would be "missing the point and wandering off into the mist",
not "following my argumentation".

| (If you think you're on the safe side as a Lisp user here, you are
| not. Since where is the difference between extending and changing a
| language and inventing a new one? You must ask yourself why you're
| not programming in some ancient Lisp? Due to idiots which were
| unable to express themselves in those dialects, obviously.)

Could you please calm down and _think_ before you try this again?

If you don't have to build a new compiler and runtime system and
support tools just because you had a new idea, you don't have a new
language. That's where the difference lies. This is pretty obvious
if you aren't dead set on disagreeing with everything I say just
because you feel obliged to spout some trivially obvious

| It takes some repeated reconsideration and starting over again and
| again from scratch while trying to keep the good stuff, get rid of
| the bad and invent a few new bits.

Really? Is that how it works?

| Where what's "good" or "bad" or "desirable new stuff" is to a great
| deal a matter of taste and therefore in the big picture -- random.
| Some languages survive, most die as experiments. Looks like sheer
| darwinism. Nature has achieved a lot by such mechanisms.

Nature is a murderer, not a nurturer. Nature does not achieve, it
destroys. Nature is what keeps each species from over-populating
their habitat. Natural selection doesn't mean the survival of the
fit, it means the death of the unfit. Whatever survives isn't fit,
either, it just wasn't unfit enough to die, and thus grow diversity
that may some time in the future determine fit and unfit. Whatever
Nature has done, it's sheer _accident_ heavily slanted towards death
and misery. Poverty and hunger is the natural condition. This goes
against a lot of mumbo-jumbo new-age mystic crap and those fools who
think there is a God figure holding a hand over them to make Nature
_not_ kill them at random and for no reason whatsoever. To Nature,
humanity is an over-populating pest. We have to _fight_ Nature all
the time to survive, because Nature is what comes up with Ebola and
AIDS and all kinds of diseaes and death. Human beings come up with
medicine and a reasonably decent way to organize society in order to
reduce, minimize, or remove the effects of Nature, like letting
people live long, rewarding lives in the blistering heat of Texas
(except those that George W. Bush ignores completely or executes,
also at random and for no good reason -- he's the Natural President)
or the death-trap cold of places like Norway.

Those who believe Nature is benevolent are insane. The benevolence
lies solely in the human capacities for compassion and intelligence
which we use to predict the course of Nature and shelter each other
from it, and to exploit the course of Nature and let each other
benefit from it. It's because we beat down Darwinism tha have the
kinds of societies we have. Social Darwinism means plunging all 6
billion people into disease-ridden poverty and a life expectance of
about 25 years at birth, so that a few could have a 50-year life and
heaps and heaps of whining little kids, about 90% of which would die.

Don't fucking talk to me about Darwinism, you undead misfit.

| > There are people who have to design their own alphabets or spellings
| > in order to feel able to express themselves, but I think we label
| > them "insane" rather than applaud them as "language designers".
|
| People are different. People express themselves in various ways.

Thank you, Dirk. I really had _no_ idea we weren't all identical.
Here I thought I could just ramble and rant and everybody would of
course agree with everything and nobody would for a second think of
coming up and tell me the Truth about People. But, Whoa! We're,
like, _not_ identical! Christ on a tricycle, I can't just assume
that everybody are _exactly_ like me? Man, that sucks. Really,
what would I _do_ without you to tell me these Important Truths?

What worries me most is actually that you think you have a point.

| Some discuss in newsgroups, others paint, some design programming
| languages. People experiment. This does not mean they're insane,
| nor stupid, nor incompetent idiots, nor does any other of Naggum's
| most frequently used attributes apply.

No, but they still apply to you. Thank you for demonstrating that.
Go play in traffic and be naturally selected, now. Thank you.

Dirk Zoller

unread,
Oct 21, 2000, 3:00:00 AM10/21/00
to
Erik Naggum wrote:

> Could you please calm down and _think_ before you try this again?

Thanks, but was and still am absolutely calm.

> | Where what's "good" or "bad" or "desirable new stuff" is to a great
> | deal a matter of taste and therefore in the big picture -- random.
> | Some languages survive, most die as experiments. Looks like sheer
> | darwinism. Nature has achieved a lot by such mechanisms.
>

> Nature is a murderer, not a nurturer. [...tonsof...]
> Those who believe Nature is benevolent are insane. [...even more...]


> Don't fucking talk to me about Darwinism, you undead misfit.

(LOL!)

You're again missing the point. For the programming languages out there,
what is the nature? The "nature" is all other programmers. Some programming
languages "live" on because they are used, others "die" because they're not.

There is nothing cruel about this. Unless you feel so compassionate towards
your language, that for you there lies cruelty in all those incompetent
other programmers out there not being a comfortable habitat for your pet
programming language.


(Now you please also calm down, Erik. I'm meanwhile used to your style
and won't enter into any further exchange of insults with you.
After all, those transport no interesting thought nor information but
only bad feelings, which I'd anyway have to pretend.)

BTW certain newsgroups are also sort of closed habitats and there are
some strange beasts to discover!

Boris Schaefer

unread,
Oct 21, 2000, 3:00:00 AM10/21/00
to
Erik Naggum <er...@naggum.net> writes:

| Yes, multiple languages have benefits. Are those benefits tied to
| multiple languages? I don't think they are. I think they are tied
| to curiosity, creativity, never being fully satisfied that you have
| found the best solution, and enough humility to listen to others and
| their ideas too It would _not_ be a good thing for a programmer to
| _have_ to learn multiple languages to be able to use new concepts,
| yet that's exactly how I see most new language come into existence:
| Some (relative) idiot can't bring himself to implement his concepts
| (which may well be brilliant and truly new) in an existing language,
| so he goes off discarding everything others spent years building so
| he can have his pet concept easily expressed. That's nuts, really.

I agree that _if_ language designers would not so easily go and create
completely new languages but instead would seriously try to implement
their ideas in an existing language then learning various languages
might not be as rewarding as I consider it to be. That's just not the
current state of the world.

I believe that you can only implement truly new concepts in an
existing language if that language allows you to treat its code as
data, and since the popular languages are not capable of this I doubt
that we will soon see the language designers become concept designers
and converge on some existing language.

| There are people who have to design their own alphabets or spellings
| in order to feel able to express themselves, but I think we label
| them "insane" rather than applaud them as "language designers".

This reminds me of Richard Feynman who wrote[1] that in high school he
once invented and used all new and different symbols for his math
which he considered superior, but which he discarded after having
noticed that he needed to communicate with others.

Boris

[1] `Surely You're Joking Mr. Feynman', Richard P. Feynman

The steady state of disks is full.
-- Ken Thompson

Boris Schaefer

unread,
Oct 21, 2000, 3:00:00 AM10/21/00
to
Dirk Zoller <d...@onlinehome.de> writes:

| For the programming languages out there, what is the nature? The
| "nature" is all other programmers. Some programming languages "live"
| on because they are used, others "die" because they're not.

Arguing from use to usefulness is not very useful. Most programming
is done in inferior languages after all.

On the whole, I'd rather be in Philadelphia.
-- W.C. Fields' epitaph

Erik Naggum

unread,
Oct 21, 2000, 3:00:00 AM10/21/00
to
* Dirk Zoller <d...@onlinehome.de>

| Thanks, but was and still am absolutely calm.

_Absolutely_, even? That would explain the absence of thought and
other brain activity. If you aren't even stirred the littlest bit
by what I told you, you are probably a dangerous lunatic who feels
as calm when actually killing as when just talking casually about
it. I'm not comforted by the fact that you post from Germany with
that emotional dysfunction.

| (LOL!)

At what other times to you laugh out loud when you don't understand
that you're talking about death and misery? Do you think _Darwin_
failed to realize that only by the death of the masses does the
species advance? He's acutely aware of it, and he was depressed
that people at home took his ideas about Nature to apply to humans.
But not a German idiot! No, no, no! Darwin is good for humans,
too! It's been only 50 years, but by God, keep the Germans in check
lest they advance their Social Darwinism ideas.

| You're again missing the point.

Do you think this is a game where the guy who last says that wins?

| For the programming languages out there, what is the nature? The
| "nature" is all other programmers. Some programming languages
| "live" on because they are used, others "die" because they're not.

And you think "Darwinism" is applicable in such an environment? Do
you at all understand what evolution is about? It's about accidents
of mutation and random changes that fall into the category "not
lethal before giving birth" while they are insignificant, but then
they may become what separates the living (as in: those most able to
have offspring -- individual _lives_ do not count in Darwinism) from
the dead some time long into the future relative to where they first
occurred. For this model to work with programming languages, first,
the languages would have to evolve on their own, languages spawning
languages randomly, and, second, they would have to be selected
according to some essentially random criteria by programmers, who
would not stick with a language, but choose a new one each time,
like you don't stick to eating some abstract "vegetables", you eat
different _physical_ ones each time. I'm sure this model fits your
very unevolved intellectual capacity, but if you think anyone who
understands the least bit about the process of evolution and
Darwinism beyond the slogan "survival of the fittest", which seems
to be your upper limit to appreciation, would find your idiotic
analogy useful, that's an insult to intelligence as a phenomenon.

Evolution works so well because about 99% of the offspring of each
generation dies before they can themselves give birth. After we
reach such incredibly advanced stages as human beings (yourself
excluded by your own admission), this process stops working because
the cost of giving birth to more and more complex beings takes more
and more resources and longer and longer time, which leads to that
anti-evolutionary concept of _caring_ for each offspring not just
while young and in need of parental shelter, but for life. Normal
people don't shoot and kill mentally retarded or sterilze them so
they won't have children. Some Germans who believed in what you
believe in did that, you know. You don't care about that, do you?

We humans, you excluded, obviously, don't "evolve". First, we keep
even the children whom Nature would have killed. Second, we try not
to engage in the enormous waste that is natural competition (the
closest we have is Microsoft's predatory romp through intelligent
life), but find that our resources are so sparse that we must think
carefully to avoid serious mistakes. This means we get a lot
further before a mistake kills something, which Nature does not. We
humans can do on purpose and with forethought in a single generation
what Nature requires millions of generations to produce by random
_because_ we don't wantonly kill everything at random, like you want
us to do because you were somehow spared that process and feel
charmed or something.

You see, Dirk Zoller, the idea of "individual" has actually made it
into the human meme pool. We no longer talk about the advancement
of the _species_ by sacrificing individual people. We deal with
individuals one by one. As an individual, that means you no longer
have that very easy escape of just dying if you make a mistake: You
have a responsibility (or should I say Pflicht to a German?) to do
more than comes "naturally", which would be to sit on your ass and
do nothing, least of all think, as long as the food comes basically
for free. This isn't about bringing the most genes to the next
generation, anymore, Dirk, it's about what you do in _your_ life.
This isn't about producing something new all the time, despite what
you see in the TV commercials, but what you do with what you have.

As it happens, all human endeavors are about what they do while
people are alive, because that's what's going to outlive us. We're
past the brutal, German philosophy of killing those who don't fit.
Except for the Middle East, most people on this planet have figured
out that it means more to have something to live for than something
to die for. This also includes working hard to save companies,
familes, values -- you don't just abandon them. This also means
caring for something, a concept that I'm sure is so foreign to you
that you have to laugh out load, again, when you see what people
care about: A cat, a programming language, an air gun or two
(Walther, of German make, btw), the intellectual property rights of
an employer's production of financial news, the violation of human
rights in the collection of taxes in Norway, the conservative
American response to FDA approval of RU 486, the failure of most
people to consider anything but the best possible scenario of the
application of their ideas. I care. You can't even _pretend_ to
feel, Dirk Zoller.

| There is nothing cruel about this.

Then you understand exactly nothing about what you're talking about.
Which is, like, today's biggest surprise. What's next? "The Origin
of the Programming Languages" by Dirk Zoller? At the very least
Charles Darwin was a scientist with respect for the scientific
method. You're just a nuthead who can't even read his theories.

| Unless you feel so compassionate towards your language, that for you
| there lies cruelty in all those incompetent other programmers out
| there not being a comfortable habitat for your pet programming
| language.

Now I know you are so fantastically devoid of intelligence that you
are forever prohibited from accepting input from the outside world.
This explains your need to laugh out loud when you should have made
the connection that explains why Germany _still_ is the culture on
this planet with the worst record and worst prospects when it comes
to _not_ understanding how an idea can turn into a killing machine.

| (Now you please also calm down, Erik. I'm meanwhile used to your style
| and won't enter into any further exchange of insults with you.

That you are "used to my style" means you _are_ an idiot. People
who have a grain of clue manage to figure this out and change their
ways to get a different style, that of respect for an intelligence
at work that learns. You are obviously not one of those, and you're
damn _proud_ of it, too. And, _surprisingly_, you're German, like
most others who are proud to be wrong, and who don't stop to think
what it means to be proud to be dead wrong.

| After all, those transport no interesting thought nor information
| but only bad feelings, which I'd anyway have to pretend.)

If you _had_ the capacity to feel, you would find both thought and
information -- if you don't feel and think at the same time, you
don't _learn_ anything. My style is one where I _want_ you to feel
pain, laugh, enjoy yourself, and cringe in horror, while your brain
is doing the hard work of thinking and making connections. You, and
some other one-trick morons, are so devoid of a working intelligence
that you think that if you feel anything at all, that's the whole
purpose. I have found my style _exceptionally_ good at identifying
your kind of pre-intelligent beings. But again, the German psyche.
Good old Immanuel Kant rearing his ugly head, stopping a whole
culture from evolving by disallowing and suprressing all feeling at
the outset, which leads to fewer mistakes that cause creative leaps,
except, of course, the _really_ big mistakes where not having human
feelings is the key.

| BTW certain newsgroups are also sort of closed habitats and there are
| some strange beasts to discover!

I'm glad you're enjoying yourself, but you're the clown. If you had
the capacity to feel shame, you would have stuck your head in the
nearest toilet and flushed it down by now. But I'm sure you're
still all laughing out loud and not getting a _single_ idea through
that wall that protects the part of you that would die instantly if
it were ever exposed to any _human_ feelings. Germans like you
actually scare me, because you _think_ so little about your ideas
and their effects on this world and on the lives of the people in it.

Go and actually read the works of Charles Darwin, Dirk Zoller. They
aren't about economics or social processes or programming languages
or how groups of people interact. If a connection is found between
biology and how we build societies, it is _not_ in the process of
natural selection. The economy is _not_ a part of nature that obeys
an extrapolation of the theories discovered to apply to evolution.
I also recommend all of what Richard Dawkins has published. In The
Blind Watchmaker, for instance, he uses simple computer programs to
show how evolution works over vast stretches of time. That might be
able to hold your attention, as you seem to be very narrowly focused
on one thing at a time, and now it's programming languages. Widen
your scope, Dirk Zoller. Don't just _pretend_ that you know about
the outside world. Feel, think, learn. Care. Be _human_. And
quit espousing ideas that, with just a little consideration of the
source and likely consequences in your specific culture, means you
felt nothing, did not think, did not learn, and do not care.

Or laugh out loud, again. At least you're good at that, Dirk Zoller.

Dirk Zoller

unread,
Oct 21, 2000, 3:00:00 AM10/21/00
to
Boris Schaefer wrote:
> | For the programming languages out there, what is the nature? The
> | "nature" is all other programmers. Some programming languages "live"
> | on because they are used, others "die" because they're not.
>
> Arguing from use to usefulness is not very useful. Most programming
> is done in inferior languages after all.

It was not my intention to argue this way. I was only making a trivial
observation in reply to a misunderstanding.

I just don't think it is a good idea to claim the evolution of programming
languages should stop because there are already good languages available.
Even excellent languages fail to attract programmers. Then again in some
sense lesser are invented in the hope to achieve some progress on a broader
base of users. This won't stop and why should it?

Dirk Zoller

unread,
Oct 21, 2000, 3:00:00 AM10/21/00