-ted
It's controverisal, but my opinion is "yes, it's useful".
I used to not like it but was gradually won over, though I think good
style means avoiding using its total power and sticking to things that
are straightforward to read.
The reason some people don't like it is simple syntax--it's not grouped.
Something like
(loop for i from 0 to 100 for j from 3 for z in z-list do (something))
ought, some say, be grouped like
(loop (for i (from-to 0 100))
(for j (from 3))
(for z (in z-list))
(do (something)))
or at least
(loop :for ((i :from 0 :to 100)
(j :from 3)
(z :in z-list))
:do (something))
so that Emacs can more easily indent it or so that programs didn't need
a special parser to understand it. Nevertheless, loop advocates defend
the syntax as simple and important to be uncluttered by the extra parens.
Ignoring the syntax, though, and just accepting that it is what it is (and
what it has been for several decades), the fact is that it provides important
capabilities of concisely representing the generation and collection of
quantities in a very useful way. Not the only way that has ever been come
up with, but still *a* useful way.
For a long time, I preferred to write
(do ((l list (cdr l))
(result '() (cons (f (car l)) result)))
((null l) (nreverse result)))
But though this has the usefulness of paralleling Scheme's tail recursive
(let foo ((l list)
(result '()))
(if (null? l)
(reverse! result)
(foo (cdr l) (cons (f (car l)) result))))
in the end, I couldn't justify to new users why they shouldn't just write
the more obvious:
(loop for item in list
collect (f item))
And sure, you could also write
(mapcar #'f list)
but the point is that if you want to change the accumulation from collect
to max or min, you can't make a trivial edit to fix that, whereas with the
loop one you can do
(loop for item in list
maximize (f item))
Likewise, things like dolist only make it easy to step the easily-steppable
data structures. If you wanted to step a package in synch with a counter,
you'd have to mix binders. e.g.,
(let ((i 0))
(do-external-symbols (s "COMMON-LISP")
(incf i))
i) => 978
Whereas with loop you can do this in a consolidated way:
(loop for symbol being the external-symbols of "COMMON-LISP"
count t)
=> 978
Basicallly, a lot of standard idioms are there and it's really quite
definitely worth being able to use it.
- - -
The other things that are controversial are the fact that some aspects
of LOOP seem unnecessary at first blush. It has conditionals, for
example. One is sometimes led to write
(loop for x in y
when (f x)
do (g x))
when one could as well write
(dolist (x y)
(when (f x)
(g x)))
Looking at such an example, one might ask why WHEN is there at all. But
the answer turns out to be that it's *very* hard to write a macro in CL
that has a "detached" piece of syntax. So you need to have a way to get
to the collect point, and it's often in a conditional. Consider:
(loop for x in y
when (f x)
collect (g x))
This one you can't write as
(dolist (x y)
(when (f x)
(collect (g x))))
Nor is there another macro (even LOOP) that you could substitute for dolist
that would make the "collect" part work. You *could* make a special
"collecting" macro, for example, that did
(collecting (result :type list)
(dolist (x y)
(when (f x)
(collect-into result (g x)))))
but already you're in a problem where you've detached the collection from
the generation, and if you have several of these to do they get harder
and harder.
The ability in loop to do even complex things like:
(loop for x in '(1 2 3 4 5 6 7)
when (evenp x)
collect x into evens
else
collect x into odds
finally
(return (values evens odds)))
=> (2 4 6), (1 3 5 7)
is considerably easier and clearer than some other alternatives.
Also, being able to vary the collection is handy. Consider:
(loop for x in '(a b (c d) e f)
when (atom x)
collect x
else
append x)
=> (A B C D E F)
Writing the equivalent in a dolist is trickier. Consider:
(let ((result '()))
(dolist (x '(a b (c d) e f))
(if (atom x)
(push x result)
(dolist (subx x)
(push subx result))))
(nreverse result))
=> (A B C D E F)
Now, personally, I have no trouble looking at either of these and seeing
the same thing, but I still have to admit that the LOOP form of it is
more instantly accessible not only to me but to newcomers.
Some don't like it because it seems very ALGOL-esque and they think
something Lispy would be better, but those of us who've "given in to
the dark side" basically acknowledge that sometimes other languages
have something to offer in terms of expression and it's better not to
fight things that don't seriously need fighting. People who WANT
to not use this are still free to, but those who like LOOP are not
idiots or crazy or possessed by the devil. They're just making an
engineering trade-off.
Some also don't like that there are occasionally obscure things in LOOP
you have to be careful of. It used to be in older dialects that
(loop collect x for i from 1 to 3)
would unintuitively return (1 2 3 4) because the collection came before
the iteration test, but
(loop for i from 1 to 3 collect x)
would return (1 2 3) as you might expect. In ANSI CL, we've added
constraints to LOOP that say the variable stepping clauses have to
precede the collection parts, so this can't happen. Nevertheless,
there may be a few ways you can still confuse yourself with LOOP.
For example, you might think
(loop with i = (random 100) for x from 1 to 10 do (print (list i x)))
and
(loop for i = (random 100) for x from 1 to 10 do (print (list i x)))
meant the same in English, but you *must* know that FOR means to do the
action every time around the loop, while WITH means to do it only once
before starting. This is a major difference but people who make the
mistake of thinking loop is "just English" are going to get confused
by "apparent synonyms" (a.k.a. "false cognates").
Good LOOP style means knowing what the words really mean, and that
means that although it seems like the best entry point for the novice,
novices need to be more cautious than anyone about its use. That
doesn't mean "don't use it", just "use it with care". Lisp may be great
for building AI things but it does not use AI as part of its own
semantics...
Hope that helps.
| but the point is that if you want to change the accumulation from collect
| to max or min, you can't make a trivial edit to fix that, whereas with the
| loop one you can do
|
| (loop for item in list
| maximize (f item))
As long as we're on that topic: how can you have a (simple) loop that
maximizes return a compound structure instead of the maximized value?
Something like:
(defclass foo ()
((name :accessor name)
(weight :accessor weight)))
(let ((foo1 (make-instance 'foo :name "foo1" :weight 10))
(foo2 (make-instance 'foo :name "foo2" :weight 9)))
(loop for foo in (list foo1 foo2)
maximize (weight foo))
This will return 10. I want it to return foo1. Is there some easy
way to accomplish this with maximize?
--
bo...@uncommon-sense.net - <http://www.uncommon-sense.net/>
The opposite of a correct statement is a false statement. But the opposite
of a profound truth may well be another profound truth.
-- Niels Bohr
Unfortunately, Paul Graham is pretty vague on the _reasons_ he does not
like "loop", and as such, his recommendations cannot be trusted, etc.
Ignore his hostility towards it. "loop" is simply _way_ useful. If you
are blinded by an irrational desire for syntactic purity that is thwarted
by the slightly unusual "loop" form (which demonstrates excellently how
you can build mini-languages in macros in Common Lisp), maybe you are
better off looking at Scheme? Paul Graham has some pretty bizarre Scheme
envy, too, which is another reason not to trust his recommendations.
Scheme people hate iteration, except when they run around in perfect
circles, cursing and re-cursing Common Lisp's iteration constructs.
///
Seems surprising, but Paul Graham thinks Common Lisp sucks:
Some quotes from "Being Popular" by Paul Graham, March 2001 :
"The political correctness of Common Lisp is an aberration."
"A more serious problem is the diffuseness of prefix notation. For
expert hackers, that really is a problem. No one wants to write
(aref a x y) when they could write a[x,y]."
"The good news is, it's not Lisp that sucks, but Common Lisp."
The original is there : http://www.paulgraham.com/popular.html
OK, a last funny one:
"Using first and rest means 50% more typing. And
they are also different lengths, meaning that the arguments won't
line up when they're called, as car and cdr often are, in successive
lines. "
Sigh...
Marc
> Kent M Pitman <pit...@world.std.com> writes:
>
> | but the point is that if you want to change the accumulation from collect
> | to max or min, you can't make a trivial edit to fix that, whereas with the
> | loop one you can do
> |
> | (loop for item in list
> | maximize (f item))
>
> As long as we're on that topic: how can you have a (simple) loop that
> maximizes return a compound structure instead of the maximized value?
>
> Something like:
>
> (defclass foo ()
> ((name :accessor name)
> (weight :accessor weight)))
>
> (let ((foo1 (make-instance 'foo :name "foo1" :weight 10))
> (foo2 (make-instance 'foo :name "foo2" :weight 9)))
> (loop for foo in (list foo1 foo2)
> maximize (weight foo))
>
> This will return 10. I want it to return foo1. Is there some easy
> way to accomplish this with maximize?
It's unfortunate that the ability to define other loop-paths was omitted
from the standard, since most implementations have such a thing.
Some things I think you have to just code longhand.
(loop with best-foo = nil ;untested
for foo in (list foo1 foo2)
when (or (not best-foo)
(> (weight foo) (weight best-foo)))
do (setq best-foo foo)
finally (return best-foo))
All in all, I think this is still pretty readable, though I'd accept
the classic
(let ((best-foo nil)) ;untested
(dolist (foo (list foo1 foo2))
(when (or (not best-foo)
(> (weight foo) (weight best-foo)))
(setq best-foo foo)))
best-foo)
as equally good in this case. LOOP isn't, as spec'd, a panacea
for everything. But its usefulness decays relatively gracefully,
allowing you to fall back on weaker clauses rather than just
having you fall out of it suddenly if you reach a thing you can't
do in the totally-easy way.
The beauty of Lisp is that function follows form. The uninitiated often laugh at
all the parentheses in a Lisp function. The Lisp expert however sees in those parens
the structure of the code. It's like looking at the framework of a building being
built and being able to envision the function of every part of it.
The loop macro ruins this. You have an opening paren and a closing parens and then
a collection of english words with stuff in between. There is no longer any structure
visible. You have to read the form as you would a novel with very obscure
and convoluted sentence struture. (see http://www.bulwer-lytton.com/ for convoluted
sentence structure examples).
Everyone who've I've seen attracted to the loop macro starts out swearing that they
will only use it for simple loops but soon get loop fever and it's a challenge to them
to write the most obscure unreadable loop macros they can, using every single loop
macro keyword.
my advice: Avoid loop like the plauge. Stick with all those parens. Make it your
goal that your code will not only work but will be readable and modifyable by others.
Yes it may take more characters to write your code. So what. Yes you may find
yourself building the same frameworks over and over again (e.g. to collect results
from an iteration) but as Kent pointed out when you read this code you recognize
common idioms like this simply from the structure. In fact you can see what the code
is doing from the framework alone (the paren layout) without even reading what's
inside the parens.
Learn Lisp first. Give it a chance before you start in on the loop language.
-john foderaro
franz inc.
This is a reasonable statement against what may be seen bad with the LOOP
macro - but then I still do not understand how you could then recommend the
usage of your IF* macro which IMHO destroys too the structure of Lisp code
you speak above. With IF* it is even worse because probably through the
nature of it I've seen that often alot of "normal structured" Lispcode is
used between the THEN ELSE a.s.o. tags (sometimes more than fits on a
screen!!!). It has the same problems like LOOP with editors like EMACS
but brings IMHO not very much gain instead of a questionable kind of
syntactic sugar that could be better done by appropriate use of IF, UNLESS
and WHEN.
In your style-guide you furthermore advice against the usage of WHEN and
UNLESS with arguments that sound IMHO more plausible for Scheme then for
Common Lisp (IF, UNLESS and WHEN would be ambigous concepts)
For those that really want to avoid "unlispy syntax" I would recommend then
to avoid IF* and better use IF, WHEN and UNLESS appropriate and furthermore
use the ITERATE macro instead of the standard extended LOOP macro.
ciao,
Jochen
I would say that LOOP is a immensily useful thing that can make certain
things alot easier to do (as Kent already pointed out).
I think the key is to recognize when _not_ to use LOOP.
It is imho nicer to write e. g.
(dolist (i '(1 2 3))
(print i))
than
(loop for i in '(1 2 3)
do (print i))
or
(dotimes (x width)
(dotimes (y height)
(setf (aref *map* x y) (+ x y))))
instead of
(loop for x from 0 below width
do (loop for y from 0 below height
do (setf (aref *map* x y) (+ x y))))
If you don't need the special accumulation features (collect, nconcing,
append, maximize...) or the more declarative arithmetic FOR loop:
(loop for i from m to n by o ...)
then it is probably a better idea to use the other facilities.
> Someone has to speak for the people who dislike the loop macro so
> it might as well be me.
Thanks for volunteering! It's hard to debate with "unnamed others".
> The beauty of Lisp is that function follows form.
"The". Hmm. Surely there are other beauties. Also, there are bound to be
exceptions, and I think there are good reasons to believe that LOOP and
FORMAT, with their "alternate languages", occur in places that one might
reasonably expect such exceptions to crop up.
I/O is quite complicated, yet not always "important" (in the sense of
wanting to be the visual focus). Yet in Maclisp before FORMAT was common,
the use of
(progn (terpri)
(princ '|There |)
(princ (cond ((= n 1) '|is|) (t '|are|)))
(princ '| |)
(let ((base 10)) (princ n))
(princ '| |)
(princ name)
(cond ((not (= n 1)) (princ '|s|)))
(princ '| here.|))
would completely dominate the landscape, making it hard to find the
computation. We still fall back to this kind of thing once in a while, but
we gave up our general syntax in the common case to gain something very
valuable: conciseness and focus.
Likewise, for iteration, the business of generating, filtering, and
accumulating is very heavily idiomatic and to go and *implement* it every
time instead of to call up the idiom makes it necessary for people to
repeat sometimes-obscure incantations that they ought not to have to know
and that sometimes might even improperly optimize for a given implementation.
I agree it loses a little of the elegance you cite, but not irrationally.
There is a very definite gain to be had.
> The uninitiated often laugh at
> all the parentheses in a Lisp function. The Lisp expert however sees in those parens
> the structure of the code.
Is this a proposal that the correct fix to LOOP is a different way to
parenthesize it? If not, it seems like smokescreen. If so, I'd be curious
to see your proposed parenthesization. I've found in my few tries that it's
painful to do because some groupings either divide things that ought not be
divided or don't divide things that ought. e.g.,
for x from 3 to 5
Should this be
(x (from 3) (to 5))
and if so what about the from-to relationship? or
(x (from-to 3 5))
in which case what about the (from 3)/(to 5) associations?
> Everyone who've I've seen attracted to the loop macro starts out
> swearing that they will only use it for simple loops but soon get
> loop fever and it's a challenge to them to write the most obscure
> unreadable loop macros they can, using every single loop macro
> keyword.
I've never seen this happen. We must have a non-overlapping set of
acquaintances.
> my advice: Avoid loop like the [plague]. Stick with all those parens.
But what goes in them? I posted several LOOP examples that I don't think
were candidates for any hypothetical obfuscated-lisp award. Perhaps you
could go through those and post your preferred alternative.
Destroys? I don't see that at all. In fact if indented properly
(we supply the emacs code to do this) then it actually displays
the structure of a conditional far better than any alternative.
Yes if* has english language 'keywords' (then, else and elseif)
but unlike loop you don't have to read the keywords to know
what the code does. They just exist to separate parts of
the conditional.
For example you can write (if* aaaaaa then bbbbbb else cccccc)
but you can't write (if* aaaaaa else cccccc then bbbbbb).
You know that after the predicate will be a 'then'. You don't
even have to read it. The 'else' is there just so you know
that cccccc doesn't follow bbbbbb which you don't see in
(if aaaaaa bbbbbb cccccc).
With loop you must read every keyword to understand what's going on.
Readability is in the mind of the reader. AllegroServe is an example
of a large program written in the style I prefer (no loop macro (other than the no
keyword version), no if, when and unless). Everyone can judge for themselves whether
this style works. (source available at ftp://ftp.franz.com/pub/aserve/ )
> Kent M Pitman <pit...@world.std.com> writes:
>
> | but the point is that if you want to change the accumulation from collect
> | to max or min, you can't make a trivial edit to fix that, whereas with the
> | loop one you can do
> |
> | (loop for item in list
> | maximize (f item))
>
> As long as we're on that topic: how can you have a (simple) loop that
> maximizes return a compound structure instead of the maximized value?
>
> This will return 10. I want it to return foo1. Is there some easy
> way to accomplish this with maximize?
It's not quite what you're asking, so raising this is this context is
perhaps a little cheeky, but my quest for making people aware of
wheels and reinvention leads me to suggest googling on
groups.google.com for "lisp morally-biggest" (this is not meant to be
intuitive), which will lead you to a dubious implementation of a
decent function. There were followups with better implementations
(O(n) rather than O(n^2), for instance).
Cheers,
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)
> In article <9mb3r4$t1q$1...@rznews2.rrze.uni-erlangen.de>, j...@dataheaven.de
> says...
>> This is a reasonable statement against what may be seen bad with the LOOP
>> macro - but then I still do not understand how you could then recommend
>> the usage of your IF* macro which IMHO destroys too the structure of Lisp
>> code you speak above.
>
> Destroys? I don't see that at all. In fact if indented properly
> (we supply the emacs code to do this) then it actually displays
> the structure of a conditional far better than any alternative.
This is a question of personal taste I fear - but IF* is definitely similar
controversial like the extended LOOP facility.
> Yes if* has english language 'keywords' (then, else and elseif)
> but unlike loop you don't have to read the keywords to know
> what the code does. They just exist to separate parts of
> the conditional.
>
> For example you can write (if* aaaaaa then bbbbbb else cccccc)
> but you can't write (if* aaaaaa else cccccc then bbbbbb).
> You know that after the predicate will be a 'then'. You don't
> even have to read it. The 'else' is there just so you know
> that cccccc doesn't follow bbbbbb which you don't see in
> (if aaaaaa bbbbbb cccccc).
> With loop you must read every keyword to understand what's going on.
in
(if aaaaaa then bbbbb elseif ccccc then ddddd else eeeee)
I have to read the keywords if I not indent the clauses appropriate (which
no bulk emacs will do right!)
But
(if aaaaa
bbbbb
(if ccccc
ddddd
eeeee))
is automaticall indented right by emacs
and even
(if aaaaa bbbbb (if ccccc ddddd eeeee))
is easier to glance at for me because the inner if is nested appropriately.
I see no real gain in doing it like IF* does - It did not happen very often
to me that I've written an IF were I really had to place an PROGN to
encapsulate the clauses. IMHO IF ic nicely indented by Emacs&Co. so that it
is pretty readable where the then and where the else clause is.
(if condition
(then-clause ..)
(else-clause ..))
against
(if* condition
then
(then-clause ..)
else
(else-clause ..))
Besides of the fact that it maks the code unnecessary longer it leads to
the problem that the clauses are indented on the same level. If the clauses
are a bit bigger than shown here the little else is visually vanishing
between.
> Readability is in the mind of the reader. AllegroServe is an example
> of a large program written in the style I prefer (no loop macro (other
> than the no
> keyword version), no if, when and unless). Everyone can judge for
> themselves whether
> this style works. (source available at ftp://ftp.franz.com/pub/aserve/ )
Yes I know - and since I spent enough time with AllegroServe to port it to
e. g. LispWorks I can say that IF* is most of the times more difficult to
decipher for at least me and up to now all other contributors I've spoken
to.
For Portable AllegroServe we have chosen to let the IF* that are already in
unchanged since changing it would be more hassle than ignoring it. But
we've chosen too that all new written/rewritten code avoids the use of IF*
and use extended LOOP too where appropriate (since e. g. the use of the
simple LOOP is in most cases a bad decision since it hides the iteration to
deeply in the code).
Please see this as constructive critique - I'm telling you only of my
experience with e. g. IF* in general and besides that AllegroServe. I think
it is a good thing to get response - if it's positive or negative.
I'm not suggesting that loop can be fixed either by adding parenthesis or coming up
with ways of indenting it to make it understandable. It's a lost cause.
There is a point to be made about this though:
==== from kmp:
Yet in Maclisp before FORMAT was common,
the use of
(progn (terpri)
(princ '|There |)
(princ (cond ((= n 1) '|is|) (t '|are|)))
(princ '| |)
(let ((base 10)) (princ n))
(princ '| |)
(princ name)
(cond ((not (= n 1)) (princ '|s|)))
(princ '| here.|))
==== end kmp
I believe that what you are saying is the format in Common Lisp introduced a new
language to save us from having to do I/O like above, and since that was a good thing
then maybe loop's introduction of a new language for iteration is a good thing as well
too.
Let's look at your example though. It took you very little time to write that after
knowing what you wanted it to do, and I'm sure that everyone read it very quickly and
figured out what it did instantly.
Now I challenge everyone to write the equivalent using Format. Time yourself to see
how long it takes.
<i'll pause here while you go do it>
..
..
..
..
Time's up..
here's my solution with a test case (i'm sure there are other ways of doing it)
(format t "There ~[are~;is~:;are~] ~:*~d ~a~2:*~p here." 1 'ball)
Can you read it and tell me without trying it whether it works or not?
Give it to a co-worker who hasn't seen this thread and ask him/her what it prints? How
long until you get an answer?
There's no question that the format string is more concise. But is using it better?
Is writing code with the least number of characters always best or is it important to
write code that others can read and understand without reaching for the Lisp manual.
Another great example from kmp:
=== from kmp
For example, you might think
(loop with i = (random 100) for x from 1 to 10 do (print (list i x)))
and
(loop for i = (random 100) for x from 1 to 10 do (print (list i x)))
meant the same in English, [but they don't do the same thing in loop]
=== end kmp
loop lulls you into thinking that you understand the program since you understand
English. Make no mistake about it, loop is its own language. If you use it you
condem everyone who reads the code to also learn the loop language.
-john foderaro
franz inc
Just as an example to the others about what we're talking about I took a code segment
out of AllegroServe wrapped in a defun for realism and I'll show you what it looks
like with if* (the foo function) and if (the bar function).
One of the problems I have with the if special form occurs at the of the bar
function. It's pretty easy to get confused and think that the dotimes at the end is
always executed. At first glance you may not see the indentation difference between
the if and dotimes. I've seen code where people put in comments like ";else" before
such a clause since they see the problem too. All if* does is enforce that 'else'
comment (in effect).
(defun foo ()
(if* text-mode
then
; here is where we should do
; external format processing
#+(and allegro (version>= 6 0 pre-final 1))
(multiple-value-setq (buffer items tocopy)
(octets-to-string
mpbuffer
:string buffer
:start cur
:end (+ cur tocopy)
:string-start start
:string-end (length buffer)
:external-format external-format
:truncate t))
#-(and allegro (version>= 6 0 pre-final 1))
(dotimes (i tocopy)
(setf (aref buffer (+ start i))
(code-char (aref mpbuffer (+ cur i)))))
else
(dotimes (i tocopy)
(setf (aref buffer (+ start i))
(aref mpbuffer (+ cur i))))))
(defun bar ()
(if text-mode
(progn
; here is where we should do
; external format processing
#+(and allegro (version>= 6 0 pre-final 1))
(multiple-value-setq (buffer items tocopy)
(octets-to-string
mpbuffer
:string buffer
:start cur
:end (+ cur tocopy)
:string-start start
:string-end (length buffer)
:external-format external-format
:truncate t))
#-(and allegro (version>= 6 0 pre-final 1))
(dotimes (i tocopy)
(setf (aref buffer (+ start i))
(code-char (aref mpbuffer (+ cur i))))))
(dotimes (i tocopy)
(setf (aref buffer (+ start i))
(aref mpbuffer (+ cur i))))))
> loop lulls you into thinking that you understand the program since
> you understand English. Make no mistake about it, loop is its own
> language. If you use it you condem everyone who reads the code to
> also learn the loop language.
This is only a problem if you foolishly assume that loop is English.
It's ALGOL-inside-Lisp, which is a great example of how Common Lisp
tries to support a variety of styles. Personally, I tried to suck in
my Algol-like-languages gut until I really got a feel for programming
in lisp, but now I love that I can let it hang out. I would expect
that people who spent less time in Algol-like languages would think in
Algol-ish terms less, and thus find less of a need for loop. The same
as how people who grew up in Smalltalk are going to eat up CLOS, and
spend a lot more of their time writing in CLOS, than others.
My natural instinct is to throw a bunch of different styles at a
problem and use what sticks. I'll occasionally go thousands of lines
without a loop form, but when it sticks, I use it.
I agree that it's syntax is rather a different breed from the rest of
lisp... but one thing it shares with the language as a whole is the freedom
to abuse its features. I've always thought loop gives you more rope than
you'll probably ever need, certainly more than enough to hang yourself!
As strictly "newbie" advice, I would say make sure your problem can't be
solved easily with mapcar, dotimes or dolist first, but if loop makes it
easier why hobble yourself?
Coby
--
(remove #\space "coby . beck @ opentechgroup . com")
"Ted Sandler" <tedsa...@rcn.com> wrote in message
news:3B88815A...@rcn.com...
...
> Everyone who've I've seen attracted to the loop macro starts out
> swearing that they will only use it for simple loops but soon get
> loop fever and it's a challenge to them to write the most obscure
> unreadable loop macros they can, using every single loop macro
> keyword.
>
> my advice: Avoid loop like the plauge.
Ahem! ... and then use IF* when working with ACL?
Sorry, I couldn't resist. :)
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'.
> (format t "There ~[are~;is~:;are~] ~:*~d ~a~2:*~p here." 1 'ball)
You've made it artificially hard and you seem to think this would make it
hard to write. You *can* do it that way, but you don't have to. Anyone
who is straining will not spend a long time looking up hard ways, they'll
do it the same easy way I'd have written:
(format t "There ~:[are~;is~] ~D ~A~P here." (= n 1) n name n)
> Can you read it and tell me without trying it whether it works or not?
No, but I can trivially vary the args and execute it in an interactive
environment to see if it works, and thereafter I can just glance at it and
say "seems like it's doing the right thing, glad it's not taking up much
space".
> There's no question that the format string is more concise. But is
> using it better?
You lived through those days of Maclisp and its companion dialect
"Franz Lisp" (no relation to Allegro CL for those of you who weren't
there). I'm surprised you can ask this. I still have my old code
listings and it's obvious at even just a glance that this was a change
100% for the better. No question. It's like the change from Assembly
language to a higher level language. Formatted I/O is nitpicky and
you can either let it take over your visual space or you can beat it
into submission by a compaction technology like this; I vote for the
latter. But we didn't quash the long-winded way in the process; we
retained both styles and people always have the option. It's *plain*
by inspecting the code of most people these days that we made a good
choice giving people this option; moreover, for those who aren't
satisfied there are other alternatives.
I'm not advocating LOOP-only nor FORMAT-only. I'm advocating that they
are well-placed in the language because they appeal to a large audience,
and I'm further arguing that that audience is not characterized by the
oversimplistic attribute "tasteless". There are good and even tasteful
reasons for using both of these. Using LOOP and FORMAT certainly do
not uniquely define taste. I'm not arguing that your desire to use
something else is tasteless. I'm not arguing that there weren't aesthetic
trade-offs made. But I think it goes a little far to say "avoid it like
the plague".
> Is writing code with the least number of characters always best
Absolutely not. But I haven't argued that. I have argued that code which
reasonably focuses the reader on things the reader cares about is important.
For example, LOOP's ability to name intent ("collect", "maximize", etc.)
is a virtue independent of code length that is lost in other variants of
code which might "implement" but not "express" that idea. In particular,
the idiom of push-push-push-nreverse cannot be argued, I finally decided of
my own code (which used to use this heavily), to be perspicuous as to the
fact of its collection of a forward list. It's an idiom that implements
the collection of a forward list but it looks weird as all get-out. LOOP
fixes that by hiding whatever accumulation technique it uses. Further, LOOP
*also* allows implementational flexibility to do better than I would have
done, and that is also an aesthetic which goes beyond simple numbers of
characters.
> or
> is it important to write code that others can read and understand
> without reaching for the Lisp manual.
You set up the straw man of the hard to read FORMAT string, but I don't
think it has to be that way. I think people should try to keep things
simple. And I often resort to combinations of Lispy iterative techniques
and FORMAT rather than use some of the more baroque list and conditional
accessors. However, I don't mind it when others don't; I trust them to
have debugged what they did (partly) and when I don't I just construct
a test case, which usually is quite easy.
> Another great example from kmp:
>
> === from kmp
>
> For example, you might think
> (loop with i = (random 100) for x from 1 to 10 do (print (list i x)))
> and
> (loop for i = (random 100) for x from 1 to 10 do (print (list i x)))
> meant the same in English, [but they don't do the same thing in loop]
>
> === end kmp
>
> loop lulls you into thinking that you understand the program since
> you understand English. Make no mistake about it, loop is its own
> language.
We do agree on this code being something you have to learn to read,
but I think this is a manageable risk.
> If you use it you condem everyone who reads the code to
> also learn the loop language.
Somewhat. Though mostly only if really trying to debug the code. Code
will often have tremendous subtlety that one doesn't see at first blush.
One usually just goes ahead and glances at it and trusts it until one
zooms in--and I find it helpful if, when in this mode of scanning from
high above, like a bird looking for a place to land, if the general
landmarks are clearly marked. LOOP does that. It draws my eye to the
fact that a list traversal is happening, or a count is being done, etc.
Then I can debug it if I have to, but that's very useful skimming info.
So there are two issues: how do I debug a LOOP (which I agree can involve
a bit of care) and how do I let a probably-debugged LOOP guide me (which
can help a lot, though if it's not really debugged can be confusing).
Still, merely learning "caution" in over-believing LOOP is important.
Btw, one other factor we didn't mention and that's debugging. The only
way to debug an out-of-control LOOP is by macroexpanding it. You can't
always visually step it (though modern LOOP can do this a little easier
than some of the earlier LOOP variants you and I grew up on). I agree
that's an issue, but again I think it's manageable.
> Boris Schaefer <bo...@uncommon-sense.net> writes:
> > As long as we're on that topic: how can you have a (simple) loop that
> > maximizes return a compound structure instead of the maximized value?
>
> It's unfortunate that the ability to define other loop-paths was omitted
> from the standard, since most implementations have such a thing.
I agree to the point that I load the MIT-LOOP code in Lispworks and
shadow CL:LOOP and CL:LOOP-FINISH, but I don't see how add-loop-path
can be used to solve this problem.
--
Lieven Marchand <m...@wyrd.be>
She says, "Honey, you're a Bastard of great proportion."
He says, "Darling, I plead guilty to that sin."
Cowboy Junkies -- A few simple words
| John Foderaro <j...@unspamx.franz.com> writes:
...
| Is this a proposal that the correct fix to LOOP is a different way to
| parenthesize it? If not, it seems like smokescreen. If so, I'd be curious
| to see your proposed parenthesization. I've found in my few tries that it's
Are you aware of Iterate
<http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/iter/iterate/0.html>?
(The distribution archive contains two Postscript documents (the
manual and "Don't Loop, Iterate" paper) that make good reading for
those unfamiliar with the package.) I think it comes pretty close
to a nice "parenthesized LOOP". Then again, I also think it is
even too close to a parenthesized LOOP in some ways.
| painful to do because some groupings either divide things that ought not be
| divided or don't divide things that ought. e.g.,
| for x from 3 to 5
| Should this be
IMO, there are two alternatives depending on how generic FOR you
want. If you want a LOOP-like FOR that can assign to the given
variable numbers of some range, elements of a list, vector etc., I
think your example should be:
(for x (scan-range :from 3 :to 5))
The version for the elements of a list would be:
(for x (scan '(1 2 3)))
If you know Series, you should realize that what I just depicted is
FOR that assigns to its first argument elements of series given as
its second argument. FWIW, I might have used shorter RANGE instead
of SCAN-RANGE if I didn't want to use existing scanners from the
Series package. Also note that I'm not saying this is what I think
the full Series-FOR syntax should be; it is just what is needed to
handle your example.
If you don't want that generic FOR, then I think your example
should/could be:
(for x :from 3 :to 5)
While you _could_ make this kind of FOR at least as generic as
LOOP's FOR (obviously not as generic as the Series-FOR above,
though), I think it would be a bad idea. A better idea would
probably be to have a separate form (actually, more than one form
might be needed) for iterating over the elements of different
containers.
| > my advice: Avoid loop like the [plague]. Stick with all those parens.
|
| But what goes in them? I posted several LOOP examples that I don't think
| were candidates for any hypothetical obfuscated-lisp award. Perhaps you
| could go through those and post your preferred alternative.
I haven't read the whole thread but I'm sure those examples would
be handled nicely by Iterate.
--
Hannu
Yeah, ick! That description kind of reminds me of stuff like this:
(if* (not (probe-file orig-dxl))
then (setq prev (rename-file dxl-file orig-dxl))
elseif (not (probe-file old-dxl))
then (setq prev (rename-file dxl-file old-dxl)))
> Everyone who've I've seen attracted to the loop macro starts out swearing
> that they will only use it for simple loops but soon get loop fever and
> it's a challenge to them to write the most obscure unreadable loop macros
> they can, using every single loop macro keyword.
You have seen my code. I do not do that. I have seen lots of other
people's code, and they do not do the horrible things you conjure up.
Please do not insult people's intelligence so gravely by pretending that
you do not know that you exaggerate wildly and irrationally and that you
think nobody would be smart enough to arrest you for it. They do, and it
makes your point ridiculous and dishonest. Coupled with the fact that
you do use that fantastic if* monster, which suffers from even more of
the problems you have described for loop, the intelligent reader will sit
back and wonder what the hell you _really_ are opposed to about loop as
none of your lofty principles apply to another obvious candidate.
> My advice: Avoid loop like the plauge. Stick with all those parens.
> Make it your goal that your code will not only work but will be readable
> and modifyable by others.
Excellent argumentation, and I mean that. Pity it is not applied to if*,
too, which is such an incredibly horrible concoction that I have a really
hard time dealing with those who use it, and not just their code. Unlike
loop, which does some pretty useful things, if* is but a wrapper around
cond to get rid of progn, making your code unreadable and unmodifiable by
those who happen to think that this is good advice, slightly paraphrased:
> Learn Lisp first. Give it a chance before you start in on the if* language.
Please get rid of if* in published Franz Inc code, and I can live with
your verbose iteration idioms and the moderately supported fear that loop
is underoptimized for political reasons. When you have cleaned up the
if* act, I will probably listen to you on a lot of other issues, too, but
as long as you rant and rave about loop while you use if*, I am sorry,
but I cannot take you very seriously. It looks too much like a religious
issue that has none of the redeeming qualities of actual religions.
///
> One of the problems I have with the if special form occurs at the of the
> bar function. It's pretty easy to get confused and think that the dotimes
> at the end is always executed. At first glance you may not see the
> indentation difference between the if and dotimes.
where the BAR function looks, in outline, like this.
(defun bar ()
(if something
stuff-to-do-when-true
stuff-to-do-when-false))
It seems to me that the blame here lies not with IF, but
with the peculiar convention, which I have never understood,
that indents the "then" and "else" parts of an IF differently.
It would almost make sense if the "else" part of an IF had an
implicit PROGN, but it doesn't.
With indentation more like
(defun bar ()
(if something
stuff-to-do-when-true
stuff-to-do-when-false))
it is much harder to miss the fact that the two consequent
clauses are indented by the same amount.
Perhaps someone can enlighten me. Why is IF so often indented
in this strange way? (Non-answer: "Because that's what emacs
lisp-mode does." So, why does emacs lisp-mode do it?)
In the particular case John Foderaro posted, the stuff-to-do-when-true
is moderately long (17 lines). If that's too long to be able to see
how the indentation lines up, well, that's a pity, but that sort of
issue arises absolutely all the time and there ought to be better
solutions than changing the syntax. Do we need a new syntax to
replace LET, with explicit end-of-scope markers? A new syntax for
function call, so you can't get confused about what function any
given thing is an argument to? That way lie XML and madness...
--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc
> (progn (terpri)
> (princ '|There |)
> (princ (cond ((= n 1) '|is|) (t '|are|)))
> (princ '| |)
> (let ((base 10)) (princ n))
> (princ '| |)
> (princ name)
> (cond ((not (= n 1)) (princ '|s|)))
> (princ '| here.|))
and a typical equivalent using FORMAT
> (format t "There ~[are~;is~:;are~] ~:*~d ~a~2:*~p here." 1 'ball)
and challenged:
> Can you read it and tell me without trying it whether it works or not? Give
> it to a co-worker who hasn't seen this thread and ask him/her what it prints?
> How long until you get an answer?
>
> There's no question that the format string is more concise. But is using it
> better? Is writing code with the least number of characters always best or
> is it important to write code that others can read and understand without
> reaching for the Lisp manual.
I think John may be missing Kent's key point.
When you write something using FORMAT, it may be harder to
read. But, by being concise, it renders the surrounding code
easier to read. The code Kent cited is certainly easier to
check than John's version using FORMAT; but embed it, along
with a few similar fragments, into something else, and *the
whole of the something-else will become hard to read*. This
is a worthwhile trade-off only if the details of the output
are more important than the computation in which it's embedded.
Even if using obscure features of FORMAT is deemed evil,
it's possible to improve considerably on the fully explicit
code Kent posted by using FORMAT more simply.
(format t "~&There ~A ~D ~A~A here."
(if (= n 1) "is" "are")
n name
(if (= n 1) "" "s"))
Incidentally, John's code is not equivalent to Kent's; it's
missing an equivalent of the (TERPRI) at the start. I think
this is an indication that fully-written-out code is not as
much easier to read as one might think.
> Kent M Pitman <pit...@world.std.com> writes:
>
> > Boris Schaefer <bo...@uncommon-sense.net> writes:
> > > As long as we're on that topic: how can you have a (simple) loop that
> > > maximizes return a compound structure instead of the maximized value?
> >
> > It's unfortunate that the ability to define other loop-paths was omitted
> > from the standard, since most implementations have such a thing.
>
> I agree to the point that I load the MIT-LOOP code in Lispworks and
> shadow CL:LOOP and CL:LOOP-FINISH, but I don't see how add-loop-path
> can be used to solve this problem.
Hmm. I haven't looked recently. You're probably right that
add-loop-path per se can't. I was speaking more generally to the
issue of adding loop keywords, by which I also meant different
accumulators. If the loop path stuff couldn't do that, I was in
error. Consider my remarks to be revised to say just that I think
it's unfortunate that LOOP isn't extensible.
> John Foderaro wrote:
>
> > One of the problems I have with the if special form occurs at the of the
> > bar function. It's pretty easy to get confused and think that the dotimes
> > at the end is always executed. At first glance you may not see the
> > indentation difference between the if and dotimes.
>
> where the BAR function looks, in outline, like this.
>
> (defun bar ()
> (if something
> stuff-to-do-when-true
> stuff-to-do-when-false))
>
> It seems to me that the blame here lies not with IF, but
> with the peculiar convention, which I have never understood,
> that indents the "then" and "else" parts of an IF differently.
One historical reason for this is that in some Lisp dialects (Lisp
Machin Lisp, I believe, and maybe others) there was an IF that took
(IF test then &body else)
so there the back-indentation helped you know when you were in the "body".
You were supposed to put your "short" side of the test first.
Another reason is that people get confused when they see:
(if (a b c d) (e f (g h) (i j (k l)) (m n)) (o p (q r) (s t)))
as to where the THEN and ELSE are. So if you put your cursor after the
IF in emacs and do C-M-f LINEFEED C-M-f LINEFEED you'll get the right
indentation AND it will be "obvious" to someone reading that line 3
of the new expression ("programs count from 0, people count from 1")
begins the else part. AND moreover, you can check the "correctness"
of this "visual claim" by pressing TAB on that line and seeing that
the line does not move.
(if (a b c d)
(e f (g h) (i j (k l)) (m n))
(o p (q r) (s t)))
> It would almost make sense if the "else" part of an IF had an
> implicit PROGN, but it doesn't.
Historically, it was. And people didn't want a billion different lisp modes.
Although if you look at my code, you'll see that it always starts with
;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Package: CL-USER; -*-
(in-package "CL-USER")
both because the Syntax info has programmatic effect on Symbolics (selecting
a sub-mode of Lips mode) and because it's a nice declarative piece of info.
(All of that notwithstanding, though, I still prefer the balanced indenting
of if, and I am constantly nudging those little else parts back over to be
lined up underneath the then part in my own code when using Emacs because
I've been too lazy to work out the init-file setup to make it indent in
the way I think of as "right".)
That's pretty funny, given how happy you are to be a part of usenet's
collective Lisp knowledge, that you don't try to take advantage of
usenet's emacs knowledge. I guess it's one of those things you only
think of when you're about to hit `space', which means you're in the
middle of something more important. Try adding this to your .emacs
file, see how you like it:
(add-hook 'lisp-mode-hook
#'(lambda ()
(setq lisp-indent-function 'common-lisp-indent-function)))
I was just trying to go along with the point you were making: format introduces a new
language just for controlling I/O. So I used that language to its fullest extent.
Imagine if 'n' and 'name' in your example were computed values. You would have to
change your code to let bind variables to the computation of those values. I wouldn't
have to change a thing. I thought that's the point you were getting at when you
mentioned the power of an imbedded I/O language (which effectively has a let form
since you can go back to certain argument values repeatedly).
Your use of format is so simple that there are plenty of other ways to do what you've
done that don't require an imbedded I/O language. Back in the old Franz Lisp days I
had a 'msg' macro that expanded into a sequence of print's of its arguments. So I
would write something like
(msg :newline "There " (if* (= n 1) then "are" else "is") " " n " "
name (if* (not (= n 1)) then "s" else "") " here.")
This has too much code but one could imagine extending the msg macro so you could
write
(msg :newline "There " (:bool (= n 1) "are" "is") " " n " " name (:plural n) " here.")
The advantage here is that it stays all in Lisp. I could do real lisp iteration
in the middle of the stuff being printed and then revert back to printing mode inside
the iteration using the msg macro again (for anyone who has used the htmlgen html
printer inside AllegroServe it's the same idea).
> That's pretty funny, given how happy you are to be a part of usenet's
> collective Lisp knowledge, that you don't try to take advantage of
> usenet's emacs knowledge. I guess it's one of those things you only
> think of when you're about to hit `space', which means you're in the
> middle of something more important. Try adding this to your .emacs
> file, see how you like it:
> (add-hook 'lisp-mode-hook
> #'(lambda ()
> (setq lisp-indent-function 'common-lisp-indent-function)))
Heh. That's true about when you feel the aggravation and how quickly
it passes. But also, the other thing that keeps me from doing it is
the knowledge I have the fix in any of seventeen files already locally
on my disk--just misplaced. (I don't think this is the fix I have; I
think I have a specific list of indent rules.) But I hate asking
questions I already have the answer to--knowing that it generates work
for someone to post a response to a question, I try to keep my
questions to a minimum... But since you volunteer the info, sure,
I'll give it a go. Thanks. :-)
> Perhaps someone can enlighten me. Why is IF so often indented
> in this strange way? (Non-answer: "Because that's what emacs
> lisp-mode does." So, why does emacs lisp-mode do it?)
Because emacs-lisp is one of those lisps that has an implicit
progn around the else part, I guess :-)
--
Raymond Wiker
Raymon...@fast.no
IF* looks like COND where some parens have been
replaced by keywords. LOOP, on the other hand,
is completely novel.
So if IF* has the advantage of being recognizable as
something else that is already known, then LOOP
doesn't have that advantage. And if LOOP has the
advantage of being a truly new (i.e., different from
the rest) syntactic paradigm, then IF* doesn't have
that advantage. Thus, it's possible for IF* and LOOP
to raise different (or at least only partially
overlapping) sets of hackles.
--d
Note that I did not say "IF* is definitely because of the same reasons
controversial like LOOP" but
"IF* ist definitely similar controversial like the extended LOOP facility."
The emphasis is on "similar controversial" and not "because of similar
reasons controversial"!
I personally like LOOP and dislike IF* and JKF seems to like IF* and
dislike LOOP - so it should be clear that there must be different reasons
for the critique _why_ IF* is a bad idea _even if_ LOOP is ruled as a good
idea.
The only questionable thing is if someone proposes so much the "Lisp-like"
syntax that he would rule out LOOP then it is not directly understandable
why he then chooses to add keywords to IF!
The difference is simply that I dislike IF* because I see no gain from
using it instead of WHEN, UNLESS, IF, COND... and I like LOOP not because
of it's fancy syntax but of the many possibilities it offers! (I personally
would prefer ITERATE over LOOP but the gain of ITERATE was up to now not
enough to overweight the fact that LOOP is standard)
If you don't understand why it's not because I haven't tried repeatedly to
explain why. I even have a web page explaining it and I'm sure you've seen
references to it in my source code.
I can't resist going from the sublime to the ridiculous. After
visiting the 99 bottles page I noticed they had a program for
CL and one for CLOS but none that really exercised format. So
I rolled up my newbie sleeves and came up with this (and as a
bonus, it even uses loop):
(defun bottle-song (x &optional (stream t))
(format stream "~{~&~[~^~:;~:*~@(~R~) bottle~:*~P of ~
beer on the wall~:*~[.~:;,~%~:*~@(~R~) bottle~:*~P ~
of beer.~%You take one down, pass it around,~%~
~[No~:;~:*~@(~R~)~] bottle~:*~P of beer on the ~
wall.~%~%~:*~]~]~}"
(loop for i from x downto 0 collect i)))
(bottle-song 99)
-----------
Idle hands, etc. :-)
Geoff
> Everyone who've I've seen attracted to the loop macro starts out swearing that they
> will only use it for simple loops but soon get loop fever and it's a challenge to them
> to write the most obscure unreadable loop macros they can, using every single loop
> macro keyword.
Fuck that! The main reason to use loop is for the complicated cases. You
use it for the simple cases too in order to keep in practice.
Tim
I know this document and already noted that fact earlier - but I still feel
free to disagree on your rationale...
I apologize for intruding with off-topic question, but is this supposed
to make the ELSE-clause be indented to the same level as THEN-clause?
I have this in my .emacs file, yet neither GNU Emacs nor XEmacs indent
it that way.
Regards,
rk
> If you don't understand why it's not because I haven't tried repeatedly to
> explain why. I even have a web page explaining it and I'm sure you've seen
> references to it in my source code.
>
> http://www.franz.com/~jkf/coding_standards.html
I suspect Jochen understands your "reasons" quite well, but just
disagrees with them. FWIW, the "standards" referred to at the
above url just sound like a codification of personal preferences to me,
with no convincing argument in their favour.
Don't get me wrong, you're ALLOWED to have personal preferences! But
so is Jochen.
And to fess up, I too like (well, okay, let's say "don't abhor") LOOP
and dislike IF*.
I think Lisp is really lucky to be so clear as to need so few of
these "coding standards". Anyone of you guys read the Ellemtel C++
coding standards? shudder...
--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>
GNU Emacs 19.34.1 normally indents
(IF X
Y
Z)
but with the above patch does
(IF X
Y
Z)
Perhaps a later Emacs version broke this OR perhaps you've loaded other
indent information you aren't aware of?
> I apologize for intruding with off-topic question, but is this supposed
> to make the ELSE-clause be indented to the same level as THEN-clause?
This works for me with Emacs 20.7.1 and has the
advantage of not messin with emacs-lisp
indentation.
(defun my-common-lisp ()
(set (make-local-variable 'lisp-indent-function)
'common-lisp-indent-function))
(add-hook 'lisp-mode-hook 'my-common-lisp)
HTH and excuse my english :)
--
Eduardo Muñoz
> I can't resist going from the sublime to the ridiculous. After
> visiting the 99 bottles page I noticed they had a program for CL and
> one for CLOS but none that really exercised format. So I rolled up
> my newbie sleeves and came up with this (and as a bonus, it even
> uses loop):
>
> (defun bottle-song (x &optional (stream t))
> (format stream "~{~&~[~^~:;~:*~@(~R~) bottle~:*~P of ~
> beer on the wall~:*~[.~:;,~%~:*~@(~R~) bottle~:*~P ~
> of beer.~%You take one down, pass it around,~%~
> ~[No~:;~:*~@(~R~)~] bottle~:*~P of beer on the ~
> wall.~%~%~:*~]~]~}"
> (loop for i from x downto 0 collect i)))
>
> (bottle-song 99)
This is a masterpiece! Now if only you could put it into the shape of
a beer bottle or a harp or something, you could enter it in an
obfuscated code contest with the best of them!
--
Fred Gilham gil...@csl.sri.com
I was storing data in every conceivable way, including keeping a chain
of sound waves running between the speaker and the microphone. There
was no more memory left to be had....
> Geoff Summerhayes wrote:
>
> > I can't resist going from the sublime to the ridiculous. After
> > visiting the 99 bottles page I noticed they had a program for CL and
> > one for CLOS but none that really exercised format. So I rolled up
> > my newbie sleeves and came up with this (and as a bonus, it even
> > uses loop):
> >
> > (defun bottle-song (x &optional (stream t))
> > (format stream "~{~&~[~^~:;~:*~@(~R~) bottle~:*~P of ~
> > beer on the wall~:*~[.~:;,~%~:*~@(~R~) bottle~:*~P ~
> > of beer.~%You take one down, pass it around,~%~
> > ~[No~:;~:*~@(~R~)~] bottle~:*~P of beer on the ~
> > wall.~%~%~:*~]~]~}"
> > (loop for i from x downto 0 collect i)))
> >
> > (bottle-song 99)
>
>
> This is a masterpiece! Now if only you could put it into the shape of
> a beer bottle or a harp or something, you could enter it in an
> obfuscated code contest with the best of them!
No way! Geoff should WRITE a FUNCTION that would reshape the code as
a Bottle of beer. :)
John Foderaro <j...@unspamx.franz.com> writes:
> (...) The Lisp expert however sees in those parens the structure of the
> code. (...)
> The loop macro ruins this. You have an opening paren and a closing
> parens and then a collection of english words with stuff in between.
> There is no longer any structure visible.
That's easy enough to fix when you like wrappers like if* anyway:
(defmacro loop* (&body body)
"LOOP variant which unpacks top-level lists that start with a :keyword.
Example: (loop* (:for x (:in '(:foo bar)) (:collect) x))
becomes (loop :for x :in '(:foo bar) :collect x )"
(cons 'loop (loop :while body
:do (if (and (consp (car body))
(keywordp (caar body)))
(setq body (append (car body) (cdr body))))
:collect (pop body))))
Now you can group and indent loops as much as you like.
> Everyone who've I've seen attracted to the loop macro starts out
> swearing that they will only use it for simple loops but soon get loop
> fever and it's a challenge to them to write the most obscure
> unreadable loop macros they can, using every single loop macro
> keyword.
Hmm. Is that "loop fever" warning advice to others, who'll probably
form their own opinions anyway, or is it also advice to yourself? If
the latter, don't you trust yourself not to do the same if you ever do
start down the evil loop path?
Anyway, do you have any clear idea about which combinations are bad, so
you could add syntax checks to prevent them in loop*? And maybe checks
to forbid silly things like `(:collect) i'. No "redundant" keywords
should be removed though, then you'd need to learn _two_ loop syntaxes.
(Again, I'm not asking you to actually do it. Just wondering if such a
solution could satisfy you.)
--
Hallvard
There is only one document on Lisp on the whole of the World Wide Web
that makes me _not_ want to use Common Lisp. I think that document says
much more about the religious fervor and irrationality of a supposed
"personal taste" which shows disregard and disrespect for every other
Common Lisp programmer on the planet than any concern for good code. I
happen to *like* Common Lisp just the way it is, damnit!, and both the
language and the tone and the wider implications of the statements in
this file are insults to everyone who has ever thought Common Lisp was a
great language. This file is like a "personal statement" on why women
should have breast implants and other cosmetic surgery, because, frankly,
they are _all_ butt ugly as a matter of course ("one can go on and on
about how bad natural breasts are, but we'll try to be brief") unless
_modified_ to fit the "personal taste" of particular misogynic. Repeat
the experiment of reading this document as if it were about something you
happen to _like_. Do you want to deal with a person who goes out of his
way to insult something _great_ and who thinks marring it is necessary?
But it gets worse, much worse. The exact same kind of religious fervor
and irrationality applies to several other areas. I could deal with the
IF* abomination and the exaggerated hatred for LOOP for a long time,
until I saw that the same thing happen to case in the reader. It is not
that there is a difference in taste, it was that _disresepct_ for those
who held other opinions, the _dishonesty_ of the arguments that there was
only to do this and that and not to worry about a thing, which any smart
Common Lisp programmers would know to be false, and finally, we saw that
reckless abandon that it was the _caller's_ fault if he had failed to
bind *print-upcase* back to the only value it apparently should have
around a call to a low-level function, because *print-upcase* and the
whole case stuff is somehow _wrong_ and thus removed from the language
that has been subject to cosmetic surgery. So this disrespect for Common
Lisp boils down to a pretense that Common Lisp is something it is not.
I have no idea what programming language these "coding standards" really
apply to, but it is not the Common Lisp I would like to use, and I can no
longer trust the purported Common Lisp code that whoever adheres to these
"coding standards" write because I have no idea how many other areas have
been subject to this looney programmer's "personal taste".
Until Sam Steingold got on the CLISP team and apparantly caused it to
move towards ANSI compliance, I had the same kind of distrust in Bruno
Haible's massively arrogant attitude problems towards the standard. I
want to program in Common Lisp, to use the available resources to see
what Common Lisp programs _should_ do (that is what conformance is about
-- screw portability of code -- it is portability of _knowledge_ I care
about), but here this punk goes out of his way to break with the standard
in areas that make absolutely no sense, also denouncing the language as
misdesigned and broken. Why could he not make his modifications as small
_additions_ to the standard? Something _optional_? A case for _choice_?
Why make it so _personal_?
* Alain Picard <api...@optushome.com.au>
> FWIW, the "standards" referred to at the above url just sound like a
> codification of personal preferences to me, with no convincing argument
> in their favour.
Oh, I think it reads like very convincing arguments in their favor,
provided that you are willing to share the arrogance of a person who is
pretending that Common Lisp is not a defined standard, but just a matter
of personal taste and dislikes. If you assume up front that the people
who wrote the standard and agreed on everything in a political process
are idiots who should be kicked in the ass, of course you listen to such
swaying arguments as calling if, when and unless "bogus-tree-conditional".
> Don't get me wrong, you're ALLOWED to have personal preferences! But
> so is Jochen.
You know, I do not think this is a personal preference. It is an attempt
to be a _professional_ preference. Everybody is entitled to their
_personal_ opinions, but for those of us who think _professionalism_ in
dealing with _professional_ issues is a major mark of quality in any
_professional_ programmer, personal opinions are set aside in favor of
making things work together and abiding by professional agreements.
That "coding standard" document is one of the most _unprofessional_
statements of an opinion I can think of right now. It has tainted my
previously good impression of John Foderaro's _professional_ conduct and
it makes him look like a crackpot unaware that he is a crackpot in his
profession, as well. When I work with people, I do not want to _have_ to
care what their personal issues are. I may want to for personal reasons,
but not for professional reasons. It is our _work_ that matters in the
end, and as professional programmers, that means we set aside personal
preferences that get in the way of good professional conduct. Inventing
a stupid new macro with keywords while you denounce the grammer of some
other macros with keywords because of them, only because you don't like
cond and progn and default indentation rules would have been OK if you
confined it to your personal projects, but to _publish_ it? That is like
insisting on an alternative spelling of some words you think look silly
in published literature. Certain authors get away with this because they
sell their _words_, such as poets. But when you do not sell your words,
you sell the information they are trying to convey to a general public,
you abide by community standards and spell them the standard way. If you
do not, you are telling people that you do not care what information you
are selling, you are really in the business of selling your new words.
This is why I urge Franz Inc to remove IF* from their published code. If
you are in the business of selling Common Lisp products, just follow the
standard. If you are the business of selling IF*, proceed as you have.
If John Foderaro makes it as abundently clear as I get the impression he
does that he would never write cond and progn, much less if, when, and
unless in production code, have somebody else (preferably some software)
convert his _personal_ style into _professional_ style for publication.
(This is in fact something several publishing houses do for their wacky
authors, who amazingly accept that they can blame the publisher for the
lack of artistic integrity that is required by the process of publication
and the filthy requirements of money and all that artistic crap you can
get away with as a celebrated author. However, I fail to see how bloody
"artistic" IF* can be that it would mandate a similar acceptance of an
author's attitude problems.)
IF* and its disturbed origin has become a blemish on the community. Any
community can and must deal with weird people, because that is just what
life is like, but when it becomes a weird _profession_ because some are
unwilling to put on a suit and tie when it is _required_ of them, the
whole community suffers. Common Lisp is already considered weird by
some, and the personal conduct of some Lispers does not help, but we
really do not need to deal with irrational _professional_ conduct.
> I think Lisp is really lucky to be so clear as to need so few of these
> "coding standards".
Well said.
///
Erik is right, it is so NOT about good coding practice I'm embarassed for
its author. It is only about if*, loop and an irrelevant personal dislike
of cond, when, if and unless. The tack-on, intelligence-insulting point 3
("oh yeah, use comments") is transparent and woefully inadequate as an
attempt to justify the document's title.
John Foderaro you are not living up to the responsibilities that come with
your role in the lisp community. You are not just another lisp user, free
to do as you please with no obligation to anyone.
> happen to *like* Common Lisp just the way it is, damnit!, and both the
> language and the tone and the wider implications of the statements in
[snip a very long, very harsh tongue-lashing, but lord help me, I can't
disagree with a word!]
> misdesigned and broken. Why could he not make his modifications as
small
> _additions_ to the standard? Something _optional_? A case for
_choice_?
> Why make it so _personal_?
>
> * Alain Picard <api...@optushome.com.au>
> > Don't get me wrong, you're ALLOWED to have personal preferences! But
> > so is Jochen.
But disguising them as "good coding standards" is very disingenuous.
>
[snip -see above-]
>
Coby
--
(remove #\space "coby . beck @ opentechgroup . com")
> * John Foderaro
> > If you don't understand why it's not because I haven't tried repeatedly
> > to explain why. I even have a web page explaining it and I'm sure
> > you've seen references to it in my source code.
> >
> > http://www.franz.com/~jkf/coding_standards.html
>
> There is only one document on Lisp on the whole of the World Wide Web
> that makes me _not_ want to use Common Lisp. I think that document says
> much more about the religious fervor and irrationality of a supposed
> "personal taste" which shows disregard and disrespect for every other
> Common Lisp programmer on the planet than any concern for good
> code.
Well I have to agree to what Eric says.
Following especially point 1 of the list is the road to "Lisp
whatever", 2 is one extreme opionoin about loop. But within the
Standard, 3 is the only I could agree with. Although writing "If it
isn't obvious what a function does, make a note of it", is not a good
idea. Better rewrite it that it is obvious what it does.. Well a bit
too much nit-picking I guess.
Now do we have a Standard or not? If all could agree on introducint an
if* well that's fine. But so long point one make all progams adhering
to it a new Lisp Dialect but definitly not Ansi Common Lisp.
Regards
Friedrich
Thanks for brightening my day.
> rich...@gmx.net (Richard Krush) writes:
>
> > On 26 Aug 2001 15:56:51 -0700, Thomas F. Burdick wrote:
> >
> > > Try adding this to your .emacs file, see how you like it:
> > >
> > > (add-hook 'lisp-mode-hook
> > > #'(lambda ()
> > > (setq lisp-indent-function
> > > 'common-lisp-indent-function)))
> >
> > I apologize for intruding with off-topic question, but is this supposed
> > to make the ELSE-clause be indented to the same level as THEN-clause?
> > I have this in my .emacs file, yet neither GNU Emacs nor XEmacs indent
> > it that way.
Did you evaluate the above form (either with M-C-x, or by restarting),
then open a lisp file in a new buffer? If not, nothing will have
changed yet. You can do
M-: (setq lisp-indent-function 'common-lisp-indent-function) RET
in one buffer to just test it out. If you have any more problems with
it, you should probably post to one of the emacs groups
(gnu.emacs.help, for example).
> GNU Emacs 19.34.1 normally indents
> (IF X
> Y
> Z)
> but with the above patch does
> (IF X
> Y
> Z)
And generally makes it know about CL better. It will generally indent
with-... forms correctly, too.
> Geoff Summerhayes wrote:
>
> > I can't resist going from the sublime to the ridiculous. After
> > visiting the 99 bottles page I noticed they had a program for CL and
> > one for CLOS but none that really exercised format. So I rolled up
> > my newbie sleeves and came up with this (and as a bonus, it even
> > uses loop):
> >
> > (defun bottle-song (x &optional (stream t))
> > (format stream "~{~&~[~^~:;~:*~@(~R~) bottle~:*~P of ~
> > beer on the wall~:*~[.~:;,~%~:*~@(~R~) bottle~:*~P ~
> > of beer.~%You take one down, pass it around,~%~
> > ~[No~:;~:*~@(~R~)~] bottle~:*~P of beer on the ~
> > wall.~%~%~:*~]~]~}"
> > (loop for i from x downto 0 collect i)))
> >
> > (bottle-song 99)
>
>
> This is a masterpiece! Now if only you could put it into the shape of
> a beer bottle or a harp or something, you could enter it in an
> obfuscated code contest with the best of them!
Heh. I agree. Quite the cute piece by Geoff, and a good suggestion by
Fred to boot. Here's my "contribution"...
- - - - - 8< - - - - - Cut here - - - - - 8< - - - - -
(in-package "CL-USER")
(defun bottle-song (&optional (in-stock 99) (stream *standard-output*))
;; Original idea and primary coding by Geoff Summerhayes
;; <sNuOmS...@hNoOtSmPaAiMl.com>
;; Formatting idea by Fred Gilham <gil...@snapdragon.csl.sri.com>
;; Actual formatting & minor recoding by Kent M Pitman
;; <pit...@world.std.com>
(format
stream
"-----~2%~
~{~&~1&~
~[~^~:;~
~1:*~@(~
~R~) bo~
ttle~:P o~
f beer on t~
he wall~01:*~[.~
~:;,~%~1:*~@(~R~
~) bottle~:*~P ~
of beer.~%You t~
ake one down, p~
ass it around, ~
~01%~[*No* more~
~:;~:01*~@(~R~)~
~] bottle~:*~P ~
of beer on the ~
wall.~2&-----~%~
~1%~:*~]~]~}~0%"
(loop for bottle from in-stock downto 0 collect bottle)))
(bottle-song)
<blush> High praise, thank you all.
For me, this qualifies as a good reason to celebrate.
Anyone else getting thirsty? <g>
Cheers,
Geoff
I've written a lot of lisp code and I've read and debugged a lot of lisp code
written by others. I have the right and responsibility to codify my experiences
with the hope that others can learn from it. Some are so blinded by faith that
they believe that everything in the CL spec is divine. The fact is that it was
designed by committee. It was a compromise. Not everything in it is a great
idea, or even a good idea.
The sad thing is that the religious zealots seem to have taken over this
newsgroup (or at least they are the loudest). I laugh at them and I hope you
do too. I hope that I can get a message through to the scientists out there who
understand that CL is just a language with good points and bad points and that
we must figure out how to make CL better and continually relevant to the current
computing world.
-john foderaro
franz inc.
Wade
> You guys make it sounds like the ANSI CL standard was handed down by
> God and it dare not be criticized.
I didn't see anyone say that.
> It's not only our right to criticize it it's our *responsibility*. The
> language will never get better if we don't.
I don't think anyone disagrees here.
> I've written a lot of lisp code and I've read and debugged a lot of lisp
> code written by others. I have the right and responsibility to codify my
> experiences with the hope that others can learn from it. Some are so
> blinded by faith that they believe that everything in the CL spec is divine.
> The fact is that it was designed by committee. It was a compromise. Not
> everything in it is a great idea, or even a good idea.
Still looking for the point of disagreement. Don't see it yet.
> The sad thing is that the religious zealots seem to have taken over this
> newsgroup (or at least they are the loudest).
I'll assume this refers to me. I wish you'd just name people by name so they
could respond. Responding to vague references always feels weird. Who else
does this refer to? Don't you have a "right and responsibility" to say who
it is you disagree with, both so people can know not to trust them/us and
so they can fairly know they are being commented on and defend themselves?
> I laugh at them and I hope you do too. I hope that I can get a message
> through to the scientists out there who understand that CL is just a
> language with good points and bad points and that we must figure out how
> to make CL better and continually relevant to the current computing world.
No problem here per se.
I think the only thing people are disagreeing with you on are whether
labeling a few isolated comments a "coding style" is fair. It would be
as if I wrote a book called "Good Form in Woodworking" and it contained
only the text: "Don't forget to sand the wood when you're done. I hate
splinters." People critiquing my "good form" book would not be meaning
"I like splinters." They would be meaning "There is more to the aesthetic
of woodworking than this and you've omitted so much as to make the title
meaningless." It might suffice to call my masterwork "One Thing To Remember
When Building Things Out of Wood", but even then, people would start to
resent the sheer number of book-covers in my collected works "Encycloopedia",
which they would imagine later including another "book" called "Oh, I forgot,
sometimes it's helpful to dust these things once in a while" (with
contained content that is a substring of the title), and "It helps to have
tools like knives or saws to cut the wood".
One reason I like attending talks on topics, even topics I don't understand
is to acquire "lists". Indeed, it's one way I judge the usefulness of a
speaker on a topic I don't understand is whether they provide me with any
kind of exhaustive partition of the space they are talking about, because
such partitions help me to understand the space of what is and is not being
talked about. A talk about "Some art is ugly." is vague and hard to put
into context. But a talk that takes a position like "Art must be either
beautiful, political, or expensive." gives me a way to evaluate the statement
it's making plus, if I buy into the statement, a way to carve out
subproblems in understanding the space.
If people are reacting to anything, it is perhaps that they've bought into
my claim that all style is about trade-off and that you can't make good
style trade-offs unless you understand the things that are being gained and
the things being lost. What's funny is that almost by definition in this
theory, there are no absolutes. I'm not advocating anyone simply believe
me all the time, nor am I advocating people ignore you all the time. The
funny thing is that you refer to "religious zealots" and people being
"blinded by faith", yet you yourself are the one who is offering up style
rules like "Never use the extended loop macro." that admit no variance.
Your own argument for this position says:
| People who use loop always say, "I just use it for small things."
| But once started down this path they can't help but use it in more
| and more complex ways until they take joy in writing code that
| cannot be deciphered.
which seems to imply that there might be acceptable uses but that you don't
want to be flexible enough to allow those uses for fear of the bad uses,
and so you'd rather also disallow even the acceptable uses. I find that
pretty uncompelling to the point of patronizing.
- - - -
By the way, also, in your point #1 you where you talk about why IF, WHEN,
and UNLESS are bad, you say:
| No other language includes an inverse conditional
You, of course, leave out the natural languages. Yes, it's true, they
aren't programming languages. However, they ARE natural, and
therefore I think prima facie evidence that it is natural to speak in
these terms. If anything, one might say, all other programming
languages besides Lisp are unnatural in this sense.
English has a single word devoted to "unless". The romance languages
typically use a construction like the Spanish "a menos que", but it does
not make appeal to negated-if. I've seen research that says that people
think of inverted conditionals more "efficiently" than negated conditionals
because they think of unless not as
consequent
/
test --- [ negate ] ---- branch
\
alternative
but rather as
alternative
/
test --- branch
\
consequent
getting exactly the speed gain that machine language does when you complement
a conditional; no increased execution time. The stuff I recall seeing (sorry,
I don't have a cite but would be willing to try to track it down if pressed)
also mentioned that it takes less short-term memory to mentally parse
statements with UNLESS because they don't add to the pile of "chunks" being
assembled, and that people can understand and competently manipulate negations
to deeper depth when UNLESS is involved than when WHEN/NOT is involved because
"Unless I'm not here, you can go out to play." doesn't feel as doubly-negative
as "When I'm not not here, you can go out to play."
This omits also discussion of the value of establishing and promoting focus
in discussion, which is why you'd want to choose between "When I'm here"
and "Unless I'm not here" ... these each have subtly different kinds of
emphasis which may be important to the speaker and are often lost in
programming languages.
I agree that natural language profits from having a
variety of conditionals and negated conditionals, but
while editing pre-existing code, having to shuffle
keywords in a way not immediately relevant to the
change at hand seems tedious and error-prone. Well, at
least I've been there. I am not sure John
Foderaro highlights _this_ particular point in favor of
IF*.
--d
In fact in this case I wasn't thinking of you. Are you a CL zealot? Here's a
way to find out. Would you insist that a collection of individuals remove use
of a macro from their published code (even if you may never see that code) just
because that macro isn't an official Common Lisp macro?
This is why I urge Franz Inc to remove IF* from their published code. If
you are in the business of selling Common Lisp products, just follow the
standard.
If you answer yes then you are a zealot.
> I think the only thing people are disagreeing with you on are whether
> labeling a few isolated comments a "coding style" is fair
English is a huge and very complex language. Yet "The Elements of Style" by
Stunk and White is only 105 pages (and they are small pages to boot). No one
has ever put them down for attempting to codify good English style in so small a
book. In fact this is the best known style guide.
I've seen a lot of Lisp code and wrote down the few rules that have the most to
do with making the code readable. I'd always planned on writing more but
nothing has irked me enough to add to the list. It's my right to publish that
and I would urge everyone else to do likewise. Try to codify what you consider
good programming style and practice it.
As for unless. Yes natural languages have it but that does not make it a good
thing for programming languages. You have to mentally insert the 'if not' and
for me that slows down the reading of the program.
> Why do I argue against ideas I don't like rather than make it personal
> and argue against specific people? (...)
Good point. Just make it specific enough that we can tell _which_
idea(s) you refer to.
> English is a huge and very complex language. Yet "The Elements of
> Style" by Stunk and White is only 105 pages (and they are small pages
> to boot). No one has ever put them down for attempting to codify good
> English style in so small a book. In fact this is the best known
> style guide.
Fair enough. Note they just call it "style", though. It was your
page's name "coding *standard*" which got to me, in particular since
"standard" has a stronger meaning in programming than in natural
language.
--
Hallvard
>
> By the way, also, in your point #1 you where you talk about why IF, WHEN,
> and UNLESS are bad, you say:
>
> | No other language includes an inverse conditional
>
> You, of course, leave out the natural languages. Yes, it's true, they
Not all of them. Hungarian doesn't have 'unless', unless you count
certain hacks that purport to fill this gap. The primary translation
of 'unless' is 'ha nem' ('if not') in the first dictionary I opened.
Not that it affects your argument. :-)
Andras
John Foderaro <j...@xspammerx.franz.com> writes:
> Why do I argue against ideas I don't like rather than make it personal
> and argue against specific people? (...)
Good point. Just make it specific enough that we can tell _which_
idea(s) you refer to.
> English is a huge and very complex language. Yet "The Elements of
> Style" by Stunk and White is only 105 pages (and they are small pages
> to boot). No one has ever put them down for attempting to codify good
> English style in so small a book. In fact this is the best known
> style guide.
Fair enough. Note they just call it "style", though. It was your
page's name "coding *standard*" which got to me, in particular since
"standard" has a stronger meaning in programming than in natural
language.
Lisp coding standards, not Franz' Lisp coding standards or Foderaro's
Lisp coding standards.
--
Hallvard
Actually, Perl has unless, for exactly the reason you give, according to the
Camel Book (Programming Perl by Larry Wall et al). I used to program Perl
for a couple of years, and I liked it's tendency to do things in ways
natural to people (and at the same time I learned to hate it's
counterintuitive ways, sloppiness and limitations).
If we look beyond trivialities like "inverse conditionals", a problem is
that people are more likely to believe that "anything goes" in languages
that use more natural (and complex) concepts, so an in depth knowledge isn't
necessary. In general, I've found that more complex languages take longer
to master, but are easier to use when you do.
Erik
> By the way, also, in your point #1 you where you talk about why IF, WHEN,
> and UNLESS are bad, you say:
>
> | No other language includes an inverse conditional
Wow, I just went and checked that to make sure it wasn't taken out of
context or misquoted, but it's right alright. It's also absolutely
false. Off the top of my head, Perl has `unless', and SmallTalk has
`ifFalse:'. Of course various assembly languages have JN* (Jump if
Not Zero, etc), which is similar.
Like most criminals who suddenly get this great political insight into
the law-making process when they get caught, you, too, confuse breaking
community standards with criticizing them. If you had criticized them
while upholding them, you would have gained respect and people would have
listened to you, because it would have meant that you would have followed
the _changing_ consensus and would be interested in helping build it.
Instead, you have a criminal mind, are a loose cannon and a person who
decides on his own when to uphold the laws and when to break them. This
is what a society of laws cannot tolerate in its citizens and community
based on a standard cannot tolerate in its members. You, sir, have no
business talking about criticizing any standards, because you obviously
would not follow a _changed_ standard, either, unless, of course, it was
your own, in which case the whole point of a standard is moot.
> It's not only our right to criticize it it's our *responsibility*. The
> language will never get better if we don't.
Most civilized people understand the difference between obeying the laws
while criticizing them and breaking them in a childish expression of
one's inability to articulate sufficiently thoughtful arguments to sway
those of a different mind to rethink their position and reach compromise.
> Some are so blinded by faith that they believe that everything in the CL
> spec is divine.
You should realize that this statement is a very grave insult to your own
intelligence and has absolutely no bearing on what anyone else thinks or
believes, simply because it is such a fucking insane thing to say.
> The fact is that it was designed by committee. It was a compromise. Not
> everything in it is a great idea, or even a good idea.
_Some_ of us prefer to live in a society where people respect each other
for their competence and professionalism despite their differences of
personal opinions and work through their conflicting desires within the
framework of compromise and imposed ritual, simply because we fully
understand what the alternative entails.
These are among the wider implications of your nutty "coding standards",
and people who are way smarter than you figured it out just reading them.
The wider implication of your incredibly stupid disrespect for compromise
is that you fully expect to _remain_ a stranger to the community. You do
not respect the fact that compromise is what makes it possible for lots
of people to work together for a common goal. That means that you do not
share in the common goal. With your disrespect for criticism of your
ways and your repetition of the exact same line of defense as last time
we fought over conformance, you have shown ourself to be an _enemy_ of
the common goal of those who base their work, money, and livelihood on
the standard and the ability of professional engineers to implement it.
I doubt that you will actually get the message, but it is not that you do
something different, it is that you are so hostile to the ways you think
you have improved upon. Case in point: I quit the SGML business when I
could no longer work with that stupid standard. I can rant and rave
freely about its braindamaged design and do any damn thing I please,
_because_ I quit working with SGML. No customers are harmed because of
my strong criticism of SGML and XML. Nobody has based their work and
their investments on my professional opinion about SGML for five years.
It is safe for me to be destructive to that community, because those who
might follow me are free to do so. I did _not_ make a huge public stink
about why SGML was a crock of shit when I quit, either. That would have
been seriously unprofessional and damaging personally to people I cared
about and who had cared about me. Actually finding a decent way out took
me half a year, but I knew I could no longer be part of that community
and I took that very seriously, both personally and professionally.
However, in your case, you are still a serious force within a serious
vendor serving this community. Your stupidity and reckless disregard for
your customers and those who still trust Franz Inc to deliver products
according to specification _will_ harm people and their investments.
This is not about IF* and LOOP, it is about whether Franz Inc will have
engineers working on their products who are professional enough to do a
good job implementing a standard they disagree with. I would frankly
want a vendor who agreed with me that the standard was good for me. This
is why I could not use CLISP, for instance -- its arrogant, nutty creator
went on record to tell the world he had broken things on purpose.
> The sad thing is that the religious zealots seem to have taken over this
> newsgroup (or at least they are the loudest). I laugh at them and I hope
> you do too. I hope that I can get a message through to the scientists
> out there who understand that CL is just a language with good points and
> bad points and that we must figure out how to make CL better and
> continually relevant to the current computing world.
>
> -john foderaro
> franz inc.
Signing that moronic, self-serving "to hell with the community" crap with
the Franz Inc company name makes it _much_ harder for me to work with
Franz Inc, and I am already strained because of your licensing policies.
I think you fail to appreciate the harm you do to your own livelihood
with the _unprofessional_ behavior you conduct in public when people
criticize _your_ supposedly "personal" opinions, which really are not at
all personal. They are your professional opinions, and while signing
with the Franz Inc company name, you indicate that if anybody wants to
deal with your company and with you professionally, they will also have
to deal with a company that goes public with a "fuck the standard"
attitude that I personally consider to be so amazingly self-destructive
that I have to question my involvement with Franz Inc because of it.
It was your retarded responses to the case issue that caused me to lose
much of my interest in helping Franz Inc the last time you aired your
stupid ego in this newsgroup, and I am frankly so disappointed with your
reckless lack of concern for the community and what it has agreed on that
I am probably not going to recommend that anyone I know use Allegro CL or
work with such an _unprofessional_ crowd as you imply that Franz Inc is
by signing with the company name. I know your position in the company
well, and I am loathe to give you business when I believe that by doing
so, I am helping you destroy the community I wish to be a part of. When
this case issue came up, and you did such a horribly unintelligent job of
it, I lost all trust in your code. I do not know which language you
really write your code in, but it is _not_ Common Lisp, and you will not
cater to those who want to use Common Lisp. You have demonstrated that
you will disregard the standard in favor of your own personal opinions,
and that is simply so _unprofessional_ that I cannot work with in _any_
professional capacity.
Just like when you blew it on the case issue and never realized what harm
you had done, this is another sad day for Common Lisp. If I were in
posititon to determine your employment with Franz Inc, I would fire you
because of the destructiveness you bring to the community, but I am not
in that position. I will, however, need to know from those who are, what
Franz Inc does to keep you away from those parts of its product line that
could be influenced by your utter disrespect for the community standard
that your customers want you to implement. I have been on your case as
long as I have worked with Franz Inc to ensure that conformance is an
issue, but as time goes on, that commitment is hollowed out by you in
particular, despite the valiant efforts of your colleagues to assure me
that conformance is a priority. Yet, you seem to take _pride_ in your
antisocial behavior and your disrespect for compromise so I leave you no
hope of recovery and will have to work around you if I continue to work
with Franz Inc, which I am, right now, inclined to terminate, but I will
calm down and consider a _compromise_ because there are things Franz Inc
does very well that I want both myself and my clients to benefit from.
In the spirit of your disdain for compromise, however, I am not going to
compromise on your position. If Allegro CL is to be seen as a viable
implementation of Common Lisp, as defined by the community you hate in
the standards document you hate, Franz Inc will have to do some serious
damage control measures to convince people that you had no opportunity to
break anything people will rely on in production systems.
I do not understand what this is _really_ about, but if you really wish
to self-destruct, please be _decent_ enough to do it away from people.
If anyone else had so many personal issues with the standard as you do, I
would have urged them to leave and find something else to do. I quit
working with SGML over less than you seem to cling to in Common Lisp.
And I hope for your personal sanity that you can afford your laughter.
///
Please take this paragraph and a what I _actually_ wrote to your nearest
psychiatric ward and ask to be committed. You need no other documentation.
Goodbye, John Foderaro. It has not been a pleasure knowing you.
///
> By the way, also, in your point #1 you where you talk about why IF, WHEN,
> and UNLESS are bad, you say:
>
> | No other language includes an inverse conditional
>
> You, of course, leave out the natural languages. Yes, it's true, they
> aren't programming languages. However, they ARE natural, and
> therefore I think prima facie evidence that it is natural to speak in
> these terms. If anything, one might say, all other programming
> languages besides Lisp are unnatural in this sense.
Not to mention Perl, which has "unless". And the various
languages that have "inverse conditionals" for loop
termination tests (the choice sometimes, but not always,
being conflated with the choice of which end to put the
test at).
--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc
>
> I am probably not alone in feeling awkward about using
> IF* because it's not "core", but I must grant that it
> seems like it would make maintaining and editing
> existing code easier. As things are now, if I modify a
> conditional by adding another branch or adding _to_ an
> existing branch, I may typically be also required to
> make changes that go beyond that simple change: such as
> reworking a WHEN or UNLESS into an IF or COND or vice
> versa, a WHEN into an UNLESS or vice versa, an IF into
> a COND or vice versa, or adding or deleting a
> PROGN. IF* avoids all that.
This may probably be true (I have made no such experiences so far)
But I personally explicitely like the diversity of conditionals
in CL because one single construct says so much more on what the code is
doing. If I always choose the "most appropriate conditional" in
a situation I can see with less work what is happening.
The simple fact of using e. g. WHEN or UNLESS gives me the immediate
information:
"There will only be a consequent no alternative"
If IF is used
"There will be exactly a consequent and an alternative"
(If you always use WHEN/UNLESS in the consequent-only case)
If you use COND
"Something more complex is going to happen - so be careful"
(since the "easy" cases are already handled by WHEN, UNLESS and IF)
Things like IF, WHEN, UNLESS, COND, CASE, EVERY, SOME, OR, AND... may in
several situations provide you immediatley with information you would have
to dig for if you would "encode" them by using e. g. IF*.
> I agree that natural language profits from having a
> variety of conditionals and negated conditionals, but
> while editing pre-existing code, having to shuffle
> keywords in a way not immediately relevant to the
> change at hand seems tedious and error-prone. Well, at
> least I've been there. I am not sure John
> Foderaro highlights _this_ particular point in favor of
> IF*.
Well... changing conditionals seems to me a bit more then merely editing
text - maybe it is worth the additional time you have to think on
_what_ is the best way to write it...
ciao,
Jochen
Does anyone else feel that I don't have the right to criticize: if, when, unless and
loop?
If it's antisocial to extend the Common Lisp language then what are we going to do
with the guy who wrote the 'iterate' macro that's been referred to so many times in
this thread. An extension that big puts my little if* to shame. Surely someone who
designs something like that is the most antisocial of all.
You readers of this newgroup set the tenor of the lisp community. Shall it be as
Erik wants where criticism of the standard is squelched, that new ideas are forbidden?
You the lisp community has to decide. Erik may speak the loudest but don't be put
off by that. Speak your own mind.
Of course you have the right to create your own macro.
Here are my thoughts when I first encountered if*. I tried to port
AllegroServe to LispWorks, the first thing I did was try to load htmlgen but
I immediately got a complaint about there being no if*. So I stripped it
out the if* since LispWorks did not have one built-in and I did not know for
sure how it worked. Its fine that ACL has a if*, but I found it annoying
trying to see how it worked in LispWorks. The main reason I did not use if*
is that I had not used it and was not familiar with its ins an outs. I
think I understood it but I did not try to play with it too much. I suppose
I could have got a compatibility package for if*, but, how could I be sure
that it behaves the same as the ACL if*?? After mulling over if* and what
it can do, I can say that I would not use it, unless I had to. I do use
loop, unless, when, cond, case, if.... Why? I have no good answer for you,
only that I am more comfortable using cond for if/else/elseif decision
handling.
As for loop, I got some old code for postscript generation from the AI
respository and I noticed code for an older version of loop. Not quite the
same, but obviously a predecessor to the CL loop. My comment is, that if
there was no loop today, somebody would invent it. It has its place because
those that programmed before, decided, through experience, that it was
needed and that it made programming easier. The reason I think it was
needed was that programmers got tired of writing the macro expansion for
loop over and over again. Eg.
CL-USER 10 > (loop for x in '(1 2 3 4 5) collect (1+ x))
expands to---->
(MACROLET ((LOOP-FINISH () '(GO #:|end-loop-461|)))
(LET ((X NIL)
(#:|tail-464| '(1 2 3 4 5))
(#:|by-465| 'SYSTEM:CDR$CONS))
(LET ((#:|accumulator-462| (LIST NIL)))
(DECLARE (TYPE LIST #:|accumulator-462|))
(LET ((#:|aux-var-468| #:|accumulator-462|))
(BLOCK NIL
(TAGBODY
#:|begin-loop-460| (PROGN
(WHEN
(OR (ENDP #:|tail-464|))
(GO #:|end-loop-461|))
(LET
((#:|temp-467|
(FUNCALL #:|by-465| #:|tail-464|))
(#:|temp-466|
(SYSTEM:CAR$CONS #:|tail-464|)))
(SETQ X #:|temp-466|)
(SETQ #:|tail-464| #:|temp-467|)))
(SETQ #:|aux-var-468|
(LAST (RPLACD
#:|aux-var-468|
(LIST (1+ X)))))
(GO #:|begin-loop-460|)
#:|end-loop-461| (RETURN-FROM
NIL
(CDR #:|accumulator-462|))))))))
Though the above is spaghetti, I think code used to be written that way for
efficiency reasons. The days of TAGBODY and GO.
You were around then, maybe you remember how loop actually came about?
As for if*, how did it come about?
Just as an aside, to make sure that every part that is being critizied is a
macro,...
The strangest thing,...
In LispWorks, loop is a function! (What the!!!!)
CL-USER 7 > #'loop
#<function LOOP 20B36F1A>
CL-USER 8 >
Wade
you absolutely have that right. No one has stated or implied otherwise.
You are misrepresenting your oppositions point of view to make it seem
ridiculous.
> Does anyone else feel that I don't have the right to criticize: if, when,
unless and
> loop?
Again, I think you have that right. We all have rights, but every right
comes with some degree of responsibility and this degree varies tremendously
on our cultural/social/business/etc positions. I offer that statement good
faith with no animosity, please think about it and please don't reply
without sincerely trying to undestand it as it applies to this whole debate,
not just the line above.
>
> If it's antisocial to extend the Common Lisp language then what are we
going to do
What is antisocial is writing something to *replace* parts of the standard
language _and_then_ *defining* good style as using your tool and only your
tool. That says "use my marbles or I won't play with you". That is
definitely anti-social.
> with the guy who wrote the 'iterate' macro that's been referred to so many
times in
> this thread. An extension that big puts my little if* to shame. Surely
someone who
> designs something like that is the most antisocial of all.
>
> You readers of this newgroup set the tenor of the lisp community. Shall
it be as
> Erik wants where criticism of the standard is squelched, that new ideas
are forbidden?
That is an unfair representation of what Erik has written. By the way, he
is not at all your only vocal opponent in this. I think you are trying to
use his controversial behaviour to gain support, regardless of the issue at
hand.
>
> You the lisp community has to decide. Erik may speak the loudest but
don't be put
> off by that. Speak your own mind.
>
If you have read my postings before, I think you know that backing down from
Erik is not one of my faults, more to the contrary...
He has made very good points about the difference between criticizing a
formally established standard and disregarding it. I'm not sure you have
tried to understand his position. I, speaking my own mind, agree. He, and
others, made good points about your document missing by a mile the line
between personal taste and sound, general advice. I agree, again. He noted
that the wording you chose and the tone you set are by implication insulting
the many fine people who do not agree. This is undeniable, really. I think
there are things in these and other arguments you should be able to
acknowledge without backing down on not liking loop and hoping to add if* to
the language.
I don't like if* from the first time i encountered it 3 weeks into learning
the language... so what (I did not know at the time it was not standard). I
see your points in its favour and they are not facile. I still would not
tell anyone to "avoid it like the plague". If I were teaching a class and
had students who used it, I would not demand that they stop. By your tone,
you would force people to stop using loop at least, and maybe even if, when
and unless. This attitude worries me *only* because of where you work. I
already find it disturbing that Franz views its customers as "Value Added
Resellers" of *their* technology. To me this is an arrogant
misrepresentation that *they* own/invented lisp. That document and your
defense of it add to my feeling that this is what you think.
Your position is as an implementer, not an inventer and not a user and that
has its own implications different from the other positions. You are
welcome to criticize ANSI CL (how could I stop you if I wanted to?) but you
damage us all by advocating its disregard and by putting down parts of it in
such an agressive manner.
That is not the issue. Such rights have never been questioned.
> Does anyone else feel that I don't have the right to criticize: if, when,
> unless and loop?
That is not the issue. Such rights have never been questioned.
> If it's antisocial to extend the Common Lisp language ...
That is not the issue. Nobody has ever even indicated that as the reason.
> An extension that big puts my little if* to shame. Surely someone who
> designs something like that is the most antisocial of all.
To those who have studied criminology and recognize the behvioral pattern
of somebody who is determined not to understand why what he has done is
under criticism, your chosen line of defense is the most incriminating
and revealing. You did this the last time you tried to defend a piece of
buggy code, too, and it showed us that John Foderaro does not back down.
Clearly, having the right to denounce the standard that your company is
asking its customers to trust it to implement for them is more important
than realizing that by your denouncing what people want to purchase from
you, you undermine your own livelihood. Further, distancing yourself
from the process and pretending to be a victim of conspiracies against
your "superior solutions" indicates that the standardization process,
which people trust to produce standards that vendors are supposed to
agree to implement, is actively _distrusted_ by you and by Franz Inc.
The message you send is not "we have something better", but instead "We
hate Common Lisp as it became standardized by a bunch of morons, but do
come talk to us if you want an implementation of that crock of shit."
Apparently, you fail to understand that you can improve upon something
without denouncing what you improve upon. You do not make something that
is better than what people already like -- you have to make them hate
what they have in order for what you have done to be better. Such is not
actually improvement -- it is the childish game of "not invented here".
This is the dangerous part of your personality and what I react to most.
The dangerous _consequence_ is that you are fully willing to sacrifice
your professionalism and other people's trust in your competence as a
programmer with a serious vendor to your personal opinion about matters
of _zero_ importance to the future of Common Lisp and its market share
and ability to solve real problems. Clearly, it is much more important
to vent your spleen about if, when, unless, and loop than to help build a
business case for Common Lisp and to help attract people to the language
("Use Common Lisp and come join the Common Lisp community and take part
in the hate campaigns against the best language on earth.").
Clearly, you do not appreciate that my trying to push Common Lisp to
people who have the money and the trust in me as a consultant that could
land Franz Inc another large contract should cause you to beam with love
for the language your products implement, but instead you spend your time
denouncing the standard and the process that created it, creating the
very strong impression in every reasonably intelligent reader of your
rantings about language misdesign that you have gone elsewhere yourself,
so why should anyone new to the language ever stick with Common Lisp?
You will probably never understand this, since you continue to believe
that you are "innovative" the same way Microsoft is, but the way you ask
people who actually happen to like Common Lisp to hate it insteead, lest
they be branded religious zealots and worse, is telling people to stay
away from John Foderaro's sick mind and anyone who keeps him employed in
a position where his blind hatred for irrelevant features causes him to
write and publish buggy code and refuse to understand that it needs to be
fixed because he thinks the problem is in the specification.
It is not your changes that causes me to react. It is your arrogance.
It is not your desire for improvements more to your liking that causes me
to react. It is your intense denunciation of everything that I need to
entrust my own livelihood and professional reputation to your products.
It is not the fact that you are a deranged lunatic that makes me want to
terminate my business dealings with Franz Inc. It is the fact that they
keep a deranged lunatic employed in a position where his utter lack of
professionalism and professional integrity may cause serious damage to my
own or my client's software in a production setting where bugs you have
introduced because you do not consider my trust in the specification you
distrust a valid concern or a reason to write correct code or to fix
bugs, and hence I will lose money and possibly face lawsuits if I _do_
trust you.
I am a businessman, John Foderaro. You are not. I deal with people's
trust in me and my competence every single day. You have never grasped
that I question your trustworthiness. To my paying clients, the only
thing that matters is my professionalism. They do not care whether I
have personal opinions about the products we use or not. I may thus love
Allegro CL _personally_ and I may grief in _private_ about the idiocy of
your self-destructive behavior, but I would be criminally unprofessional
if I asked a client of mine to invest USD 100,000 in my love for a
product that cannot be trusted to perform as required by specification
for such a fantastically stupid reason as one idiot engineer giving a
higher priority to his dislike for language features over correct code.
This is a bigger issue than you appear able to understand, John Foderaro.
Nobody cares what you think about if, when, unless, and loop when they
face a delay in deployment because of one of your bugs. Nobody cares
about your silly coding standards when a project folds because a feature
in the specification is not supported for "political reasons". We have a
standard, and nobody cares where it came from, God, Devil, committee, or
John Foderaro, but everyone in the kinds of businesses I deal with care
that it is actually and faithfully implemented. Based on the evidence
that you provide about your priorities for Common Lisp and your own code,
I _must_, because I am a professional, decline to suggest that people who
would be willing to invest several hundred thousand dollars over the next
few years on their trust in my word, invest it in Allegro CL.
In short, your insistence that you be allowed to denounce the standard,
the standardization process, us "zealots", and everyone who disagrees
with your fantastically stupid "improvements" and "coding standards", has
a pretty hefty price tag. Your employer needs to understand that your
desire for a John Foderaro Lisp instead of a Common Lisp has caused me, a
fairly strongly devoted fan of Allegro CL, to abandon Allegro CL as the
choice implementation platform. I do not personally consider there to be
viable alternatives, which means that we will probably use a different
language. Now, this has not just happened this once, the last time we
had a fight over your prioritizing your personal opinions over correct
implementation of specified language features, I did not even bother to
waste my time arguing for Common Lisp. That project went with Java,
simply because I was too personally exhausted by your idiotic behavior to
want to fight for Allegro CL. I know I could have won that project.
The question I put towards you, John Foderaro, is this: Does it matter so
much to you to be able to denounce that which people come to you and to
Franz Inc to purchase that you are willing to let go of customers who do
not like that denunciation and who get the impression that you will do an
unprofessional job if asked to implement something you have some personal
issue with? If it matters that much to you, good riddance to both you
and Franz Inc. If you can get through your thick skull that maybe you
can get what you want if you back down and start to behave professionally,
maybe, just _maybe_, it is possible to get Franz Inc to take conformance
seriously and actually put fixing deviations from the specification on
top of the list of prioritized tasks and thus help rebuild its trust.
> You readers of this newgroup set the tenor of the lisp community. Shall
> it be as Erik wants where criticism of the standard is squelched, that
> new ideas are forbidden?
That is not the issue. That is not what I do. It is not criticism that
you engage in, it is a political campaign of distrust in the process that
created the standard. If it were criticism, you would respect the
process and its results. You do neither. If it were criticism, you
would trust the process to yield better results with better input. You
very obviously do not believe this, but instead take it upon yourself to
do what you will, regardless of process or procedure.
> You the lisp community has to decide. Erik may speak the loudest but
> don't be put off by that. Speak your own mind.
Yes, let us see a show of hands from the all people who do understand the
issues of trust, conformance, respect for procedure, and compromise in
order to gain something _higher_ than immediate personal satisfaction.
I used to have doubts that you were mentally incapable of understanding
the issues that surround your antisocial behavior and your strong disdain
for the community standardization process, but I have been forced by the
sheer mass of evidence that you yourself provide to conclude that you do,
in fact, not have the mental apparatus to understand what standardization
means for a community and for the trust one may have in products. The
concept of trust in professionalism is probably also forever beyond your
reach as you continue to behave in the most _unprofessional_ way I have
seen anyone in any community ever do. Your immense lack of honesty and
personal integrity when it comes to representing the views and opinions
of others contributes to your lack of understanding of what other people
are trying to address. This are further strong indications of a deeply
antisocial personality. Your behavior in regard to the case issue and
the line of defense you choose when under criticism for your rampant
disregard for community "compromise" in favor of "John Foderaro's way",
whatever the cost may be, indicates that you are incapable of dealing
with more advanced concepts of cooperation than "do it my way or no way".
Since this is also how you interpret any criticism towards you, it seems
highly unlikely that you have the ability to understand what the issues
are surrounding your conscious and willful destruction of the public
trust in Franz Inc's commitment to implement a conforming Common Lisp
implementation and the construction of a reciprocal distrust towards the
antisocial behavior of Franz Inc when it comes to breaking the standard
in order to push some miniscule changes for personal reasons.
I concluded that I could not trust you or _any_ of your code when you
flat out _refused_ to recognize the bug in the piece of code you posted,
because I understood the full implications of your political agenda: It
is more important for John Foderaro to denounce people than to help me
and anyone else who wants to make money programming in Common Lisp with
Allegro CL. It is fairly obvious that I have the exact reverse priority.
And people wonder why Common Lisp does not "win"? It is not because of
the language, it is because of the self-destructive morons in this
community who think it is conducive to their personal goals to denounce
and ridicule and fight the common goal. John Foderaro and his case,
pathname, character vs integer, if-when-unless, loop, etc, etc, issues.
Bruno Haible and his large bunch of issues. Paul Graham and his bunch of
issues against the language. People who appear, on the surface, to have
done good work for Common Lisp return time and again to denounce the
language, its community, and everything that _could_ bind us together.
Why would anyone in their right mind want to use Common Lisp when the
people who do (seem) use it are so negative towards the language?
Over the years, people have asked me how I can make money at all doing
the things I do for a living. I have always been way, way off mainstream
and still made a reasonable living. I think the reason is pretty clear:
I love what I do and do what I love. People pick up on it and trust me
professionally because of the fact that I have a high personal investment
in what I do. Likewise, I think people pick up on those who hate what
they do and do what they hate. Judging from the behavior of a large
number of Lisp people, it seems clear to me now that the problem we have
is that people do not love Lisp and the do not use it, because it is more
important to them to hate some miniscule little misfeature than to love
the whole of it and live with the "warts", if any. It also seems to me
that people are reluctant to leave, but prefer to hang around and be
nay-sayers and negative influences on those who _want_ to like Lisp. We
see it from people who come here, too, they pick up the negative attitude
towards the language _very_ quickly. I am probably very fortunate who
can do what I do, but I honestly think that if you do not do what you
love to do, it is because you decided at the wrong time that you would
quit searching and settle for the money or something. That is _poverty_.
If you cannot love more than the money you get for doing something, at
least be smart enough to love that, and it should be easy to pretend that
you love your work so you can continue to make money. If you cannot even
pretend, why are you not searching for something better? How much effort
can it _be_ to learn a new trade or a new programming language? I mean,
_kids_ learn these things. Kids are _not_ smart. Kids do not have tons
of experience and stuff that makes things easier to learn. Kids absorb
stuff faster than grownups, but they still need a lot of time getting
used to _working_. Grownups _work_. When grownups _want_ to learn
something new, they do it way faster than kids do. At least if they are
pretty intelligent, and Lisp people are ipso facto pretty intelligent, so
there simply is no excuse for a disgruntled Lisper to hang around and be
so negative about Lisp. This makes me wonder what kind of personal value
it has to a disgruntled Lisper to hang around in the Lisp community and
denounce the language, the standard, the people behind the standard, and
nigh everything that says a _positive_ word about either or all of them.
I trust that people smarter than John Foderaro understand that criticism
is not the same as denunciation. Criticism has a fundamental respect for
that which is criticized and a desire to see it realize a potential that
it may not yet have realized fully. Denunciation is disrespect for the
potential _and_ its realization, however incomplete. Good criticism will
always see how the current realization reflects the potential, not deny
that it does, which denunciation would do. Good criticism embodies an
understanding and appreciation of how something came to be, because
nothing can really be "improved" by first breaking with its genesis --
that would be replacing a lot more than that which needs improving. This
is why "X is broken, here's an incompatible fix" is _not_ good criticism,
but bad. Bad criticism presumes that the current realization defeats the
potential without actually establishing that premise to be true. (It
does happen, unfortunately, as it does with attributes in SGML.)
John Foderaro has made this into an election and a popularity contest.
My take on this is that people who have nothing better to do than to
denounce the standard, the process by which it was created, and the
people who did it, be shot down and thrown out of the community. Let
those who _like_ Common Lisp use it, and let the nay-sayers leave us
alone to do what we think best. Those who _like_ Common Lisp will have
lots of ideas for improvement, too, but at least they can trust that the
other people they sit down with and compromise with are all good people,
instead of disgruntled nay-sayers who did not get their will last time
and never got over it. Maybe there even are things that are broken and
not well thought out, but if you like the language, you will care for it
and its users, not chop off parts according to personal distastes and
scare people off because _they_ liked the part that got chopped off.
Now I have a Common Lisp application to update with new requirements that
are easily met before its users get to work in a couple hours.
And since this is an election: Remember to vote for Common Lisp with your
heart -- it is the good language for good people. Remember who _likes_
Common Lisp when you want to trust people to take care of its future.
///
>
> Does anyone else feel that I don't have the right to define my own macro to express
> the conditional statement?
You have all the right to do so. You have no *right* to force anyone
in following you.
>
> Does anyone else feel that I don't have the right to criticize: if, when, unless and
> loop?
You can criticize is as much as you like, but you have not *right* to
force anyone in following you.
>
> If it's antisocial to extend the Common Lisp language then what are we going to do
> with the guy who wrote the 'iterate' macro that's been referred to so many times in
> this thread.
I would suggest to re-read the mails. After that you hopefully see the
difference.
>
> You readers of this newgroup set the tenor of the lisp community. Shall it be as
> Erik wants where criticism of the standard is squelched, that new
> ideas are forbidden?
Whatever Eric has said among it was not that one is not allowed to
criticice the standard.
>
> You the lisp community has to decide. Erik may speak the loudest but don't be put
> off by that. Speak your own mind.
Well again point 1 of you list is ridicolous. You put you personal
preference over other things which is fine for you, but if I want to
run the code I must either
a) use your Lisp (which with the extension of if* is definitly not
Common Lisp)
b) rewrote that Macro elsewhere.
For what do I have to do that? Because adhering to someones "personal"
standard? Well I do not want that. If I use the if, unless and when
stuff I can role my own standard without enforcing other people to
break the "standard langauge"
Well standards are of course not a one man show. That has it pros and
cons. But having a standard is a major advantage, it's existence is a
safe-net for Users, and having a standard means I'm not tight to any
specific vendor. Of course that is what vendors disklike I guess..
Better to have a standard of your own, than it's easy to force the
Users to bear all bad decisions.
Friedrich
It originated back in 1980 in Franz Lisp where it was called If (that's capital I and
a lower case f). It came about for the same reasons that it exists today, to enhance
readability of the conditional expression.
> Does anyone else feel that I don't have the right to define my own
> macro to express the conditional statement?
Not here.
> Does anyone else feel that I don't have the right to criticize: if,
> when, unless and loop?
That's fine, too.
> If it's antisocial to extend the Common Lisp language then what are
> we going to do with the guy who wrote the 'iterate' macro that's
> been referred to so many times in this thread. An extension that
> big puts my little if* to shame. Surely someone who designs
> something like that is the most antisocial of all.
Uh, no. No-one's ever said that it was antisocial to extend the Common
Lisp language.
> You readers of this newgroup set the tenor of the lisp community.
> Shall it be as Erik wants where criticism of the standard is
> squelched, that new ideas are forbidden?
This is an outrageous misrepresentation.
> You the lisp community has to decide. Erik may speak the loudest
> but don't be put off by that. Speak your own mind.
I only posted to this thread because you explicitly asked for it, to
add my voice to those who are asking you to think a little about the
issues that other people have raised.
Think, please.
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)
> Now do we have a Standard or not? If all could agree on introducint an
> if* well that's fine. But so long point one make all progams adhering
> to it a new Lisp Dialect but definitly not Ansi Common Lisp.
if someone gives me some piece of source code with IF* in it, I would
expect them to supply a macro defining IF* together with that code.
Then I would have no other reason to object than personal taste (but I
would be tempted to macroexpand away all the IF*s, if they compiled
into pretty-looking CONDs ;-)).
--
(espen)
> This may probably be true (I have made no such experiences so far)
> But I personally explicitely like the diversity of conditionals
> in CL because one single construct says so much more on what the code is
> doing. If I always choose the "most appropriate conditional" in
> a situation I can see with less work what is happening.
I like it too. For my own use (I am *not* reommending this!) I tend
to use:
IF - probably I am using the value returned (and I'd tend to give an
explicit NIL in the else branch if need be here).
WHEN, UNLESS - I'm not using the value, but I want to check something.
I often have chains of WHEN / UNLESS to check conditions are true. As
in english I pick the operator to put focus on the expected thing, so
I can end up with (WHEN (NOT ...) ...). For instance:
(when (bogusp a1)
(log-message "bogus A1 value ~A" a1)
(error ...))
(unless (or (null x) ...)
...)
;; Everything is OK ...
I could use ASSERT for this but often I don't want the automagic error
stuff, I want to do my own error protocol.
COND - multiway branch, may or may not use value. I *don't* use COND
for the kind of error-checking above, I always use WHEN / UNLESS.
And then there are CASE &c &c.
It's great that CL has so many kinds of conditional and looping
construct.
--tim
> And people wonder why Common Lisp does not "win"? It is not
> because of the language, it is because of the self-destructive
> morons in this community who think it is conducive to their
> personal goals to denounce and ridicule and fight the common goal.
What common goal? Bear in mind this is com.lang.lisp, not
comp.lang.ansi-cl.
> John Foderaro and his case, pathname, character vs integer,
> if-when-unless, loop, etc, etc, issues. Bruno Haible and his
> large bunch of issues. Paul Graham and his bunch of issues
> against the language. People who appear, on the surface, to have
> done good work for Common Lisp return time and again to denounce
> the language, its community, and everything that _could_ bind us
> together.
I did not see John's "coding standard" as an attack on the community,
a denouncement of the language, or an assault on any of the common
ideas that this community could be said to hold. He laid out a set of
criteria for judging forms and then critiqued some forms included in
the CL standard while suggesting a form not in the standard. He also
did not call his document "Common Lisp Coding Standards", so he was
not misrepresenting the language. The document also included a
disclaimer indicating that they were private opinions and not those of
Franz.
The CL standard is not the whole of the language, it is a tool for
those who use the language, much like the OED and the MLA handbook are
not english, but tools for those who use english. The issues people
have with the standard are not issues against the language, any more
than non-standard spelling or grammar is an attack against english.
While it is true that a non-negligable amount of friction is generated
by deviations from the CL standard across Lisp implementations, I see
no reason to regard those as attacks on the community. The community
is a group of users, not the standard. Lisp is a tool, CL is a tool
of the Lisp community. Tools are shaped by usage, and old tools can
became burdens for new uses and new contexts. In this way usage comes
into conflict with standards. Maintenance of the tools requires
labor, a scarce resource which is not always available, so tools will
not always be in compliance with standards.
I would hazard a guess that the maintenance of CL compliance across
Lisps, and the protection of the CL standard is not a primary goal of
many people who would consider themselves members of this community.
That common goal is to write Lisp and in doing so accomplish other
goals, like making a living in software, advancing scientific inquiry,
balancing their checkbook, or creating virtual worlds.
Perhaps this is not the case tho, and there is indeed a portion of the
community who believe that the maintenance of and adhesion to the CL
standard is the primary goal of the community. I have not seen
evidence over the last few years to support their existence in
appreciable numbers.
> Why would anyone in their right mind want to use Common Lisp when
> the people who do (seem) use it are so negative towards the
> language?
You are attacking John, and now Bruce and Paul. You say they "appear,
on the surface" to have done good work, as if there is a doubt to the
legitimacy of their work. These are people who have written or
maintained implementations in wide use today, that allow a many people
to be members of this community, to write lisp. Paul has written
books which have helped many, myself included, become more competent
in the primary goal of this community, writing Lisp. It is
disengenuous to insinuate that these works are hollow, a trick of
rhetoric.
The forms John dissed are not part of the community, those people are.
People write the code, write the documentation, maintain the
implementations, and otherwise bring life and energy to the community.
The CL standard is just a tool of the community. The Lisp community
existed before it, and will exist after it.
--
Craig Brozefsky <cr...@red-bean.com>
http://www.red-bean.com/~craig
The outer space which me wears it has sexual intercourse. - opus
> IF - probably I am using the value returned (and I'd tend to give an
> explicit NIL in the else branch if need be here).
This convention, in contrast to your not using return values in
when/unless is not one I have followed in the past, but I think it's a
very useful one and can recall several times when it would have saved
my a bug. I will attempt to remember it tommorow when I am writing
Lisp.
> It's great that CL has so many kinds of conditional and looping
> construct.
Yup, apparent redundancy can allow for nuance.
>
> if someone gives me some piece of source code with IF* in it, I would
> expect them to supply a macro defining IF* together with that code.
> Then I would have no other reason to object than personal taste (but I
> would be tempted to macroexpand away all the IF*s, if they compiled
> into pretty-looking CONDs ;-)).
Well someone else posted his problem as he wants to port some Franz
Lisp stuff to LispWorks got the sources but no IF* there. He did not
get an if* implementation. I check another thing which was given
AllegroServer and found that there is an implementation of if*. So one
can get one (hopefully a correct one) but it's work.
Regards
Friedrich
> You readers of this newgroup set the tenor of the lisp community.
> Shall it be as Erik wants where criticism of the standard is
> squelched, that new ideas are forbidden?
This is a disingenous, self-serving misrepresentation of what has
been said in this thread. I simply cannot believe it to be a
genuine mistake: I _must_ believe you are trying to deceive the
community. Which is, of course, an attempt doomed to failure, so
all it accomplishes is making you look bad.
> You the lisp community has to decide. Erik may speak the loudest
> but don't be put off by that. Speak your own mind.
Very well. Here it is. I'm a lisp user. I'm Joe Schmoe, nobody
knows me, I'm not famous, but I chose lisp for our company, and I
created lisp jobs. In short, I'm Franz Inc's target audience.
I think standards are a *good* thing.
Eh? What's that? You were expecting something deep and meaningful?
Earlier, you also wrote:
> The sad thing is that the religious zealots seem to have taken over
> this newsgroup (or at least they are the loudest). I laugh at them
> and I hope you do too.
This frankly scares me. I saw no religious zealotry, at least in this
thread, so either I'm a dunce, or _I_ am one of the zealots in
question. Might I ask: are you speaking on your own behalf, or that
of Franz when you post this? You signed:
> -john foderaro
> franz inc.
Sad. Sad and scary. A dark day for all lispers.
Alain Picard
--
It would be difficult to construe Larry Wall, in article
this as a feature. <1995May29....@netlabs.com>
> Well again point 1 of you list is ridicolous. You put you personal
> preference over other things which is fine for you, but if I want to
> run the code I must either
> a) use your Lisp (which with the extension of if* is definitly not
> Common Lisp)
> b) rewrote that Macro elsewhere.
how about
c) ask me for the code to the macro so you don't have to bother rewriting it?
So many have asked I've put it up on a web page:
http://www.franz.com/~jkf/ifstar.txt
Now do you see that the if* macro is no different than any macro you've written and
use in your code. If you are allowed to write macros to use in your code why forbid
me from writing a macro that based on my experience writing lisp code I feel makes my
code easier to write and read??? I'm not doing it to lock you out of the code. I've
freely given up the source code for the macro to anyone who asks.
I've always freely given away the source to if*
http://www.franz.com/~jkf/ifstar.txt
but what are you going to do about the fact that the code I write uses socket and
multiprocessing extensions that are unique to ACL? If I publish source (like
AllegroServe or the imap/pop/smtp module) is it antisocial to not publish all the
source for socket and multiprocessing too?
Let's face it: interesting applications are going to contain code outside the Common
Lisp spec. In fact the code to even create an application is something Lisp
implementation specific. When compared to all this, the if* macro dwindles in
insignificance. I don't see the big deal.
* John Foderaro <j...@unspamx.franz.com>:
> Does anyone else feel that I don't have the right to define my own macro
> to express the conditional statement?
You're misrepresenting what Erik, and possibly others, have been saying.
I've not seen anyone suggest that you're not allowed to define your own
macros. To suggest such a thing would be stupid. Is it your intention to
draw that parallel?
> Does anyone else feel that I don't have the right to criticize: if, when,
> unless and loop?
See above. I don't see anyone saying your not allowed to criticise. Quite
the opposite in fact (this suggests to me that you didn't actually read the
post you followed up).
> If it's antisocial to extend the Common Lisp language then what are we
> going to do with the guy who wrote the 'iterate' macro that's been
> referred to so many times in this thread. An extension that big puts my
> little if* to shame. Surely someone who designs something like that is the
> most antisocial of all.
Either I'm failing to comprehend what Erik and others have written, or you
are. I've not seen anyone suggest that writing code and extending your use
of a language is antisocial. What does seem to be under discussion here, if
I'm understanding the arguments correctly, is the actions of an implementor
of a language, not the actions of a user of a language.
> You readers of this newgroup set the tenor of the lisp community. Shall
> it be as Erik wants where criticism of the standard is squelched, that new
> ideas are forbidden?
As one of the readers you appeal to I have to say that this is an amazing
misrepresentation of what Erik has been saying. Either that or I've totally
failed to comprehend his point.
> You the lisp community has to decide. Erik may speak the loudest but
> don't be put off by that. Speak your own mind.
Why should I be put off speaking my mind because someone else has spoken
theirs? That's insulting to me as one of the readers you've appealed to.
--
Dave Pearson: | lbdb.el - LBDB interface.
http://www.davep.org/ | sawfish.el - Sawfish mode.
Emacs: | uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/ | quickurl.el - Recall lists of URLs.
> By the way, also, in your point #1 you where you talk about why IF, WHEN,
> and UNLESS are bad, you say:
>
> | No other language includes an inverse conditional
>
> You, of course, leave out the natural languages. Yes, it's true, they
> aren't programming languages. [SNIP]
There are also other programming languages that have "unless". perl and ruby
are two that sprint to mind.
First I always speak for myself.
Second did you miss Erik's points:
1. I shouldn't be allowed to distribute code that uses a macro that's not part of
Common Lisp. Franz should 'clean up' the code by automatically rewriting the code to
include only CL macros and special forms.
2. I can think ill of Common Lisp macros and special forms but I shouldn't put those
thoughts down on a web page where people can read it. To him to criticize less than
one percent of Common Lisp is to criticize one hundred precent of it and to seek it's
downfall.
If you feel that way too, and I very much doubt you do, then you are a zealot as well.
> In article <873d6bl...@frown.here>, fr...@q-software-solutions.com says...
>
> > Well again point 1 of you list is ridicolous. You put you personal
> > preference over other things which is fine for you, but if I want to
> > run the code I must either
> > a) use your Lisp (which with the extension of if* is definitly not
> > Common Lisp)
> > b) rewrote that Macro elsewhere.
>
> how about
> c) ask me for the code to the macro so you don't have to bother rewriting it?
> So many have asked I've put it up on a web page:
> http://www.franz.com/~jkf/ifstar.txt
Well I found it later while reading another article. I found it in
AllegroServer. Well that is fine. But I would not add it to a coding
standard, while puttting if, when, unless into the ground.
> If you are allowed to write macros to use in your code why forbid
> me from writing a macro that based on my experience writing lisp code I feel makes my
> code easier to write and read???
Nobody has forbiden it as far as I can see. The point was that one
*should* prefer it over established things, and not just even prefer
it but use it "exclusivly". Now I disagree I want my other things if I
feel so.
>I'm not doing it to lock you out of the code. I've
> freely given up the source code for the macro to anyone who asks.
Well that's ok, as said before I found it by accident while looking
through the LW Port of AllegroServe.
Regards
Friedrich
There's the not totally insignificant difference that sockets and
multiprocessing aren't standardized, while the core language is. There's no
_reason_ not to include such simple language extension macros in the
distributed source.
Erik
If as an implementor I was to remove if,while,unless and loop forcing people to use
if* then that would be a bad thing. Of course I haven't done that and that's never
even been brought up.
As an implementor must I blindly support everything in the CL standard and be a stupid
cheerleader. Must I be like a car salesman who stresses only the good points of the
car and purposely neglects to mention the bad points just to make a sale?
The fact is that I spend 95% of my programming time as a Common Lisp user not
implementor. I write applications and libraries in Common Lisp that are not part of
the Common Lisp spec. My interest is seeing Common Lisp succeed and as someone who
uses it day to day I feel it's my right to refine my coding style to ensure that I
write readable, debuggable, extensible code.
Now we have Erik telling everyone that I can't publish my code if it contains a macro
he doesn't like. I can't publish on the web my criticism of common lisp macros and
special forms (and gives this bogus reason: it's not professional for an implementor
to criticize the language he's implementing).
The fact is that Erik really doesn't care about if*, unless.. etc. What's really
happening here is that I was added to his enemies list a while ago. I'm not sure what
put me there but that's where I am. Given any topic and choosing any side, Erik can
turn the flame gun on and toast the other side. I guess he was bored and saw this
thread winding down, saw that a member of his enemies list was in the discussion and
fired up the flame gun. His statements have been so ludicrous that I didn't figure
anyone would buy into them (after all who's ever been flamed for using a macro they
defined themselves and the source of which is available).
This will be my last post on this thread.
You are not the first person I've seen say they don't use WHEN for its
return value and (I think?) there seems to be a consensus that it is not
good style to do so. But I do that often and confess have come to like it
very much. And I guess along with that is that I never put a NIL in the
else part of an IF, I use a WHEN.
An example coming to mind...
(setf foo (when (slot-boundp (bar frob))
(calculate-fie frob)))
> It's great that CL has so many kinds of conditional and looping
> construct.
>
Choice can never be a bad thing!
You're being delibrately obtuse. You haven't forced that, but you have
defined proper Lisp coding standards on your company website in just those
terms. You have stated that proper code can not be written otherwise. You
called if, when and unless "bogus" (what does that say about their users?).
That is why so many hackles are raised. You clearly would force people to
use if* if it were in your power.
> As an implementor must I blindly support everything in the CL standard
Yes. (I read that as support in the technical sense.)
> and be a stupid cheerleader.
No.
> Must I be like a car salesman who stresses only the good points of the
> car and purposely neglects to mention the bad points just to make a sale?
>
"This one is blue. Don't buy it, I hate blue."
Erik is not the only one concerned. There have been several other posters
whose arguments you have completely ignored.
>
> This will be my last post on this thread.
>
Probably the best strategy. You have not acknowledged one disenting opinion
on any point. Unfortunatelty, the more you write the less sincere you look.
> You are not the first person I've seen say they don't use WHEN for its
> return value and (I think?) there seems to be a consensus that it is not
> good style to do so. But I do that often and confess have come to like it
> very much. And I guess along with that is that I never put a NIL in the
> else part of an IF, I use a WHEN.
>
> An example coming to mind...
>
> (setf foo (when (slot-boundp (bar frob))
> (calculate-fie frob)))
>
This is the kind of thing I find very confusing. The problem I have
is that what this says to me, as a human reader, is that it is
completely failing to cope with the case then the test is not true.
Of course to the machine it's all fine, but that's not really the
issue here.
If it was me, I'd write either
(setf foo (if ... ... nil))
or, less functionally but perhaps more clearly:
(when ... (setf foo ...))
Of course I don't want to control how you write code for you (or
anyone else but me, really).
--tim
> John Foderaro <j...@unspamx.franz.com> writes:
>
> > So many have asked I've put it up on a web page:
> > http://www.franz.com/~jkf/ifstar.txt
>
> Well I found it later while reading another article. I found it in
> AllegroServer. Well that is fine. But I would not add it to a coding
> standard, while puttting if, when, unless into the ground.
Indeed.
Look, I have a bunch of code I've been writing that I plan to release.
It contains my own personal macros that I like a lot. I think all of us
have such. I've even gone to the trouble of making my own shadow package
with my own set of symbols in it. I wouldn't personally want a macro
called IF* because the very name itself is ugly. If I felt as strongly
as you, I'd have made a JKF-LISP package with IF, WHEN, and UNLESS outright
removed and with JKF-LISP:IF doing what IF* does. And I wouldn't expect
any whining from anyone AS LONG AS I also provided the source code in every
distributed piece of code.
For example, I WOULD expect people to beat me up if I posted here using
a modified IF (or IF*) in a coding example of an answer to a reader question
where getting the definition of that macro was left "as an exercise to
the reader". If on the other hand you posted an answer that said:
(defpackage "MY-PACKAGE"
(:use "CL")
(:shadow "IF"))
(in-package "MY-PACKAGE")
(defmacro if ...include whatever code...)
(... use of if ...)
then I think you'd be "in your rights" though people might beat you up
for not being perspicuous in your answer to the question since IF might
not be the focus of the question and your desire to make it be the dominant
piece of text in the reply might be as bad as making the guy go look it up.
Is it a pain to write in "common lisp" sometimes when you know you've got
a function or macro that will make the answer still more concise? Sure.
I program routinely with a DEFUN-INLINE macro, but I always expand it
for newsgroup purposes to (declaim (inline ...)) (defun ...). I have a
(defun-cached foo ...) that I use instead of (defvar *foo-cache ...) +
(defun foo () (or (gethash ...) (setf (gethash ...) ....))) but I expand
those things out for here.
The first thing any of us does when we get CL is start to write in it, and
the nature of writing code in Lisp is extending the language. But we can't
foist our personal extensions on one another in this forum as if they were
standard without having some very clear wayto make sure newbies aren't
confused by our having done that.
> > If you are allowed to write macros to use in your code why forbid
> > me from writing a macro that based on my experience writing lisp code
> > I feel makes my code easier to write and read???
>
> Nobody has forbiden it as far as I can see. The point was that one
> *should* prefer it over established things, and not just even prefer
> it but use it "exclusivly". Now I disagree I want my other things if I
> feel so.
This is mere personal opinion and everyone's will vary.
> >I'm not doing it to lock you out of the code. I've
> > freely given up the source code for the macro to anyone who asks.
Uh, you said before that you always speak for yourself, not Franz.
This is proprietary Franz source code, I assume. Are you empowered
for Franz to release this? There is no copyright notice, however under
international copyright convention, I believe that copyright may still
apply.
I actually _believe_ you think you do. Which is kind of scary.
> Second did you miss Erik's points:
> 1. I shouldn't be allowed to distribute code that uses a macro that's not
> part of Common Lisp. Franz should 'clean up' the code by automatically
> rewriting the code to include only CL macros and special forms.
Seems to me that you try to speak for me both now and repeatedly previously.
You do not recognize this, do you?
> 2. I can think ill of Common Lisp macros and special forms but I
> shouldn't put those thoughts down on a web page where people can read it.
> To him to criticize less than one percent of Common Lisp is to criticize
> one hundred precent of it and to seek it's downfall.
This sure looks like you try to speak for me, too. Do you fail to
understand what you are saying both directly and indirectly?
This incredibly stupid and dishonest manipulation that you engage in
fails because most people in this newsgroup are probably smarter than you
are and figure out _exactly_ what you are trying to do.
> If you feel that way too, and I very much doubt you do, then you are a
> zealot as well.
Why is it important to you that whoever says something is a zealot?
I think this quote from your own material speaks for itself:
Why do I argue against ideas I don't like rather than make it personal and argue
against specific people? There are a number of reasons. First I feel there's
a lot more content if you stick to ideas rather than hurling childish insults.
I think we have sufficient evidence to conclude that you are unable to
separate fact and fiction and neither do you actually understand how much
you are hurling childish insults and show that you are _preoccupied_ with
arguing against specific people.
The most interesting point for me, however, is watching how you squirm
away from the real issues. It is _impossible_ that you could have failed
to grasp what I have said. It is unthinkable that you do not understand
that I have directly linked your unprofessional behavior to Franz Inc's
loss of business and I believe that your continued employment with Franz
Inc is detrimental to the survivability of Allegro CL, but _still_ you
continue to argue as if you have a "right" to create new macros and
"criticize" the standard, _neither_ of which have been substantially
challenged by anyone other than your whining self.
All in all, you leave me the impression of a mentally ill person who has
lost all relevant contact with reality and have shut itself in a world
where people are trying to prevent him from doing something reasonable
when in fact nobody is preventing that, they are trying to stop you from
doing real damage to people because of the way you work to destroy the
community consensus-building processes of which you are, by your very own
admission, not party.
You also missed the point entirely, which is hardly surprising, about why
Franz Inc should remove IF* from its published code: It is because it is
professional of a serious company to keep its mentally ill "artists" away
from the public in exactly the same way several publishing houses have
and continue to accept the most insane behavior from its authors as long
as they can correct their idiosyncrasies of spelling and grammar in
print. If Franz Inc continues to publish IF*, it is not selling a Common
Lisp implementation, it is selling the works of an insane artist, the
same way an author who insists on a variant spelling is selling his
deviant spelling in preference to whatever ideas he wanted to express.
I am forced to assume that you do not understand this analogy at all.
Let me make that analogy more concrete. Suppose you think that the verb
"be" is broken and that it should be a regular verb. You write all your
documentation and correspondence with your more elegant version, publish
a "grammar standard" which explains why "be" is broken by design and why
people should avoid it like the plague and instead use your simple and
elegant be*, and you rant and rave against the complex grammar of English
and lie about there being no other languages with a complex "be" verb.
If this does not make you look stark raving mad, I do not know what would.
Now, your employer has a potential contract with a client and the client
looks at your documentation and wonders why you have devised your own
verb, at which point you decide that this is a good time to argue against
the stupid English language and its gratuitous complexity. The client is
very professional and asks you whether this opinion of yours will impact
their software, which among other things will contain a natural language
module and wisely asks for a demonstration. The natural language module
has a bug because you think "be" is broken by design and it fails to make
an important grammatical distinction. The client asks you to fix this
bug because they are not interested in your superior version of English.
You get very, very upset about this and rant and rave about your rights
to create your own verbs being infringed and clearly "be" _is_ broken!
The very professional client interprets this as meaning that it is more
important to you to keep your own verb than to do business with them, and
prepares to leave, at which point you call them "grammar zealots" and
slam the door, screaming to anryone you meet that your right to criticize
the English language is under attack and someone wants to stop your
improvements to the language. I believe the esteemed readership of this
newsgroup will appreciate that the deranged lunatic I have just described
is a _fair_ depiction of John Foderaro.
Suppose the deranged lunatic can do really useful work. A professional
employer would find ways to make use of the deranged lunatic, but would
ensure that none of the official company correspondence use the lunatic's
private verbs, that none of the documentation does, and that the lunatic
is kept under lock and key and does not harm the professional impression
of the company in the public eye. Provided that they can afford to have
someone go over the lunatic's useful work and clean it up, this might
make business sense. It does manifestly _not_ make business sense to
keep the lunatic employed in a position where he causes serious damage to
the company's public profile and image. It would be _suicidal_ for a
company to let this person loose on its clients, however professional
they be. Demanding that all customers put up with the lunatic before
they can purchase the product is simply not a good business plan.
And, yes, there _are_ serious bugs in Allegro CL that come directly from
John Foderaro's _unwillingness_ to implement the specification correctly
and months, even years, of asking for fixes have gone unanswered, as are
my suggested fixes. I have been bitten by them several times, probably
because I am a zealot who also _knows_ the standard so well that I use
more of it than most people. For all its excellent support of "real"
customer needs, you can just forget any support from Franz Inc if John
Foderaro filters the bug report and decides the bug is in ANSI CL, and if
you raise a conformance issue, you can easily get interrogated on your
supposed "real" need and are suggested work-arounds instead of getting a
"yes, sir, right a way, sir!" response that a responsible vendor of a
product that has a well-known, published _specification_ to work from
should respond with. After all, conformance to the specification is the
_baseline_ for all customer satisfaction. If you cannot trust the
product to conform to an extremely high-quality specification, how can
you trust that it does what the vendor says it does? Conformance is thus
not an end in itself -- it is a means to establish trust in the vendor's
ability to do a complete and professional job and to act responsibly in
the face of a requirements document. Instead, what I get from people at
Franz Inc when I raise this issue is that they cannot commit to ANSI CL
because it is a moving target, that anyone can change it, etc. The fact
that it is a version of a standard that is never going to change -- there
might be new versions, but not changes -- does not penetrate or register.
The fact that I use this standard as a reference for correct behavior the
same way I use their manuals for their additions does not register -- I
should use Franz Inc manuals for everything and not require any objective
measures of conformance.
Franz Inc used to be much better than they are now about this. Then they
hired another dangerous lunatic who argued strongly against conformance
because he actually _believed_ that that would make the product _less_
responsive to user needs and this person poisoned my relationship with
the company and very efficiently shut down my "better conformance" drive.
That nutball was fired as I understand it, and good riddance, but the
effects of his destructiveness lingers, and John Foderaro has picked up
all of his bitterness and venom towards the standard and the committe and
has continued to destroy my trust in Franz Inc's ability to _ever_ get
around to fix hundreds of minor conformance bugs, which they no longer
even document or keep track of. Then there's the weird shit they do with
case and John Foderaro's massively unintelligent rationale for why you
cannot write code in "modern" languages with a case-insensitive reader.
The reader's ability to be case-insensitive was actually broken by design
in the case-sensitive mode, but fortunately, there are still good people
at Franz, and this did get fixed. Now, it is not exactly rocket science
to figure out how to make a Common Lisp system use lower-case symbol
names in a way that does not mean switching the whole goddamn system from
lower-case to upper-case and back, but they consider that _sufficient_
and do not want to listen to suggestions to avoid mode switches and
multiple Lisp images.
_All_ of my frustrations with Franz Inc can be traced to the hostility
towards the standard and the disingenious excuses they engage in whenever
you want something that chiefly comes from the standard. However, I have
received so much positive feedback and real help and understanding from
nigh _everybody_ other than John Foderaro and the other fired lunatic
that I think the problem can fixed by be excising the root of the problem.
I shall therefore assume the role of the professional client in the above
concrete analogy who does not want to deal with the deranged lunatic on
staff with his peculiar verb and his demented list of priorities and ask
Franz Inc to get rid of John Foderaro and make sure that their products
are firmly based in conformance to the standard and that they grow an
understanding on all levels and fully appreciate that conformance is
_not_ a threat to any of their other high-quality products or add-ons or
extensions, but that their continued conformance issues are still a
serious detractor from their other valuable products. Being the only
serious game in town has a responsibility that I cannot tolerate is
flaunted and ridiculed the way John Foderaro does. His utter lack of
professionalism and serious business sense in dealing with conformance
issues has gone from merely annoying to central in my dealing with Franz
Inc, mostly because John Foderaro is such an arrogant bastard and so
_fantastically_ dishonest and disingenious in his passive-agressive
argumentation.
Finally, a _professional_ vendor who worked _with_ the standards process
would submit a continuous stream of documents to improve the language in
the committee, would probably get their will if they were even moderately
good ideas, and would be able to gain respect for their work, and they
would probably find a way to solve their problems if they had a person on
staff who was less irrational than John Foderaro. For all their ills,
compromise in standards committees tend to produce results when the
people who request strange things manage to avoid offending people who do
not want the same thing as them. As the evidence suggests, there is a
long-standing "war" between John Foderaro and the committee. I am not
certain, but I believe there are no others who harbor such bitterness
towards committee decisions like the case issue.
I maintain that the only _real_ problem Common Lisp has is that so many
of its purported proponents are so negative to the language.
///
> If I publish source (like AllegroServe or the imap/pop/smtp module)
> is it antisocial to not publish all the source for socket and
> multiprocessing too?
Not if you publish a clean, documented spec for the missing functions.
If you just randomly strip a page out of your source code that does lots
of bit-manipulation on undocumented quantities, then yes.
> Let's face it: interesting applications are going to contain code
> outside the Common Lisp spec.
Yes, although as you may recall from the days before CL, we used to
have infinite different libraries for how to implement even things
like LET. There was the one that implemented it as a LAMBDA
combination, the one that had a body with tags because it was
implemented as a PROG with an uncnoditional return around the last
form, and even the one that implemented LET as a DO that did not
iterate. These differences were petty. We made a standard exactly
to stem the fighiting over certain basics, so we could move on.
That wasn't a law, but it was a strong community desire. People had
bigger things to worry about than spinning their wheels forever on
issues of how these low-level things worked. We wanted to argue
about how to do multi-tasking but were held back by worrying about
the implementation of loops, ifs,, and LET. Once we have multi-tasking
down, expect us to feel annoyed that people challenge that even though
certainly by rights ANY solution we as a community adopt will leave
someone (perhaps even legitimately) unhappy. We move forward as a
community by letting certain lost causes rest.
> In fact the code to even create an
> application is something Lisp implementation specific. When
> compared to all this, the if* macro dwindles in insignificance. I
> don't see the big deal.
Depends on whether you merely use it as your own macro or you try to
advocate a holy war on settled territory. The former is fine, the
latter is not.
So you don't rely on an absent branch of a conditional
to return the overspecified value of false when the
conditional's test is false. That is so... Scheme!
--d
> "John Foderaro" <j...@unspamx.franz.com>
>
> > As an implementor must I blindly support everything in the CL standard
>
> Yes. (I read that as support in the technical sense.)
The answer here is that ANSI is a "voluntary" standard. You provide it
because you think people want to buy it. You should not be surprised that
people who want to buy a standard are miffed when you tell them you
really don't want to support the standard.
This reminds me of my basic problem about smoking areas in restaurants.
I don't mind at all someone having a big sign saying "if you don't like
smoke, don't come in." I DO mind someone putting up a sign saying
"we provide a pleasant area for our non-smoking customers" and then having
them juxtapose smoking and non-smoking tables. It wasn't me who said
"non-smokers welcome". But once they've welcomed me in there, I expect
to hear no more about how hard it is to separate the two areas. If it's
hard, don't invite me in. Or make it all-non-smoking. It's just a business
decision, but the customer should not be caught in between with
bait-and-switch antics.
> > and be a stupid cheerleader.
>
> No.
I'm even mildly unsure about this. While you aren't required to be a
cheerleader for something you sell, don't expect to keep selling to people
who want standards if you decide you can't say a kind word about them.
People don't like hearing negative things all the time about things they
like. It's just bad business.
It would not surprise me in the least to find that people who were previously
undecided about Franz have made a decision not to purchase based on your
remarks here, for example. Maybe Franz can tolerate that. Maybe even Franz
is in agreement with you and happy that youa re scaring off people who are
so focused on standards. (But I doubt it.)
> > Must I be like a car salesman who stresses only the good points of the
> > car and purposely neglects to mention the bad points just to make a sale?
>
> "This one is blue. Don't buy it, I hate blue."
Worse: "This one is blue. Don't buy it. Here take a leaflet. I'm
lobbying to have blue banned as a possible car color. Join me in my
quest to make car dealers less responsive to customers like you who
think cars should come in standard colors."
> > This will be my last post on this thread.
>
> Probably the best strategy. You have not acknowledged one disenting opinion
> on any point. Unfortunatelty, the more you write the less sincere you look.
Since John has opted out (and I agree perhaps for the best, since he's not
getting a warm reception on any of this), let me just add these words
of hope for him:
For what it's worth, though I really utterly disagree with John on the
style and taste aspects of most of his quest here, I don't think it's
unreasonable of him to hold a personally divergent opinion. I've bookmarked
his remarks on coding style to review again later so that in my quest for
people to make a balanced decision on various issues, I'll at least try
to make sure that his reservations are taken into consideration. As to
his specific recommendations, that's harder to say. But I'll take them
under advisement.
> So you don't rely on an absent branch of a conditional
> to return the overspecified value of false when the
> conditional's test is false. That is so... Scheme!
Well, I rely on it, I just find it harder to read, and I write code at
least partly (perhaps mostly) so I can read it.
--tim
> "Coby Beck" <cb...@mercury.bc.ca> writes:
>
> > You are not the first person I've seen say they don't use WHEN for its
> > return value and (I think?) there seems to be a consensus that it is not
> > good style to do so. But I do that often and confess have come to like it
> > very much. And I guess along with that is that I never put a NIL in the
> > else part of an IF, I use a WHEN.
I think this is a place where people "reasonably differ". It helps a lot
to know the conventions of who wrote the code before you start inferring
things.
I sometimes do put NIL's in the else of an IF for emphasis, but it's
rare and depends on circumstance. A good example where I do:
(DEFUN TRUE? (X) (IF X T NIL))
> > An example coming to mind...
> >
> > (setf foo (when (slot-boundp (bar frob))
> > (calculate-fie frob)))
> >
>
> This is the kind of thing I find very confusing. The problem I have
> is that what this says to me, as a human reader, is that it is
> completely failing to cope with the case then the test is not true.
> Of course to the machine it's all fine, but that's not really the
> issue here.
>
> If it was me, I'd write either
>
> (setf foo (if ... ... nil))
I sometimes do one and sometimes the other.
I always use the IF when the value to be defaulted is '() [empty list]
or 'NIL [symbol]. But when it's NIL [boolean], I'm relaxed.
> or, less functionally but perhaps more clearly:
>
> (when ... (setf foo ...))
This leaves FOO unbound (or having a prior value), of course, so is
not semantically equal in all cases. But I'll assume you mean "in the
places where it makes sense" :-)
> Of course I don't want to control how you write code for you (or
> anyone else but me, really).
I mostly use WHEN for non-value-producing situations, but I make
numerous exceptions because often I think of the WHEN as returning
a "failure" value, and if the caller is looking for a failure value
that seems good enough for me. I choose more because I reasonably do
not anticipate needing an else, or UNLESS because I reasonably do not
anticipate a then.
e.g.,
;;; In this one, WHEN marks the "cut" point where failure has
;;; occurred and I can tell by indentation that I need not look
;;; further for an alternate return value--failure of the WHEN
;;; means failure of the predicate.
(defun frob-awake (name)
(let ((frob (find name *awake-frobs* :key #'string-equal)))
(when frob
(- (get-universal-time) (frob-wake-time frob)))))
;;; In this one, there's no point to an "else" in the WHEN
;;; because the OR is already carrying "else" info, so WHEN
;;; seems right.
(defvar *foo-file*
(or (when *foo-override-dir*
(probe-file (merge-pathnames *foo* *foo-override-dir*)))
(merge-pathnames *foo* *foo-normal-dir*)))
Some people would use AND rather than WHEN in this last one.
But that's another discussion...
The more you continue to misrepresent what I have said, the more people
will realize what the real problem is. I have a profound trust in the
ability of people to see through the kind of unintelligent manipulation
that you and some really stupid politicians engage in when they run out
of arguments.
> The fact is that Erik really doesn't care about if*, unless.. etc.
From someone who has already done a marvellous job of proving that he
cannot distinguish fact from fiction, I am impressed that you found the
need to prove it to us.
> What's really happening here is that I was added to his enemies list a
> while ago.
There is no such thing outside of your deranged mind.
> I'm not sure what put me there but that's where I am.
You are not sure? Geez. You destroyed my trust in Franz Inc's ability
to be a business partner when I was looking at another Common Lisp
project. Through your amazing stupidity and your idiotic desire to break
with the standard over actually supporting Common Lisp projects, you made
it abundantly clear that I could no longer take any financial risks that
involved Franz Inc as a supplier. This did not make you an enemy, though.
> Given any topic and choosing any side, Erik can turn the flame gun on and
> toast the other side.
Yup, you're the guy who speaks only for yourself.
> I guess he was bored and saw this thread winding down, saw that a member
> of his enemies list was in the discussion and fired up the flame gun.
Geez. Disrespect for people who are smarter than you seems to be deeply
ingrained.
> His statements have been so ludicrous that I didn't figure anyone would
> buy into them (after all who's ever been flamed for using a macro they
> defined themselves and the source of which is available).
That is so not what you have been flamed for. Your constant manipulative
deception is what you get flamed for. Get some professional help.
> This will be my last post on this thread.
I wish.
///
Isn't defining little languages one of the things we're supposed
to do in Lisp? Isn't it supposed to be one of Lisp's strengths
that it's so easy? Do we believe these things only in theory,
rejecting them in practice?
The mere fact that LOOP has survived this long, and that no more
generally accepted alternative emerged during the whole process of
Common Lisp standardisation, suggests that LOOP meets some need in
a reasonably effective way.
I don't especially like LOOP, but I find that in simple cases it is
much easier to read and to understand than a written-out recursion or
any of the built-in alternatives. (I don't remember enough about
ITERATE to comment.)
The one thing I don't like (still in fairly simple cases) is that
I find it hard to remember which syntax gives me sequential value
assignment when there's > 1 iteration variable and which gives me
parallel. So I almost always stick to cases where there's only one
variable.
When Graham makes his case against LOOP (I think it's in On Lisp but I
might be wrong), he relies on examples that are unlike anything I
would even consider using in my code. Even KMP's with/for example
(below) has a bit of that.
> For example, you might think
> (loop with i = (random 100) for x from 1 to 10 do (print (list i x)))
> and
> (loop for i = (random 100) for x from 1 to 10 do (print (list i x)))
> meant the same in English, [but they don't do the same thing in loop]
Well, I don't think they mean the same in English, and if I didn't
already know, I'd guess correctly - from what I've seen in other
languages - that "with" means binding (like LET) and "for" means
iteration. But I'd avoid such combinations in any case.
Re FORMAT, I'm glad the Franz Lisp "msg" macro has finally been
mentioned. Though I do use format, I've also define a msg-like
macro that I often used in preference, especially when the FORMAT
call would take many arguments.
It's another little language, though a simple one.
-- jeff
>
> I think this is a place where people "reasonably differ".
Yes, and just in case it wasn't clear I wasn't trying to suggest that
the conventions I use should be used by anyone but me (except perhaps
for projects I controlled or somethng like that). I don't know why
I'm saying this except that there's been so much shouting in this
thread ...
--tim
> If it was me, I'd write either
>
> (setf foo (if ... ... nil))
>
> or, less functionally but perhaps more clearly:
>
> (when ... (setf foo ...))
>
> Of course I don't want to control how you write code for you (or anyone
> else but me, really).
The second example does something very different from the first doesn't it?
These will always set a value:
,----
| (setf foo (when ... ...))
| (setf foo (if ... ... nil))
`----
whereas this will only set a value if the condition is true:
,----
| (when ... (setf foo ...))
`----
> Why do I argue against ideas I don't like rather than make it
> personal and argue against specific people? There are a number of
> reasons. First I feel there's a lot more content if you stick to
> ideas rather than hurling childish insults. ...
Surely it's possible to disagree with specific people without
hurling any insults.
-- jeff