From: Software Scavenger
Subject: Coding style
Date: 
Message-ID: <a6789134.0110061517.7d25bf0c@posting.google.com>
I want to discuss Lisp coding style.  In the examples below of a
prime-factors function, the first example is closest to the canonical
Lisp coding style, but this style has problems such as higher
incidence of word-wrap when viewing in smaller windows.

The 2nd example is a style intended to reduce usage of screen real
estate.  The unless/let line is indented instead of having all the
lines below it indented, as one easy way to reduce overall horizontal
size.  Part of the logic of this is that Lisp functions tend to start
with lines that establish context/scope for all the lines that follow
them, and it's easy to give a special meaning to extra indentation of
the first lines after the defun line, because it has no preexisting
meaning.

The 3rd example is a compromise to minimize horizontal size and
maximize readability.  The indentation/structure is such that you
would read the most significant words, "first, rest, cons first rest",
and then read again to fill in the details.

For the 4th example, I use a macro, flamx, to support a style which
might seem slightly awkward for this particular example but has some
potential for neater code in other cases.  The name flamx is an
abbreviation for funcall-lambda-x.  This macro is inspired by the fact
that this style of coding would make frequent use of idioms such as
((lambda (x) (...)) ...) and such frequent use implies a reason to
shorten and/or neaten the syntax.  Other macros might supplement it,
such as flamxy, etc.  But regardless of the merits of flamx etc., it's
also worthwhile to discuss the merits in general of using macros to
support coding styles.


Example 1:

(defun prime-factors (n)
  (unless (< n 2)
    (let ((x (loop as i from 2 to (sqrt n)
                   thereis (if (= 0 (rem n i)) i)
                   finally (return n))))
      (cons x (prime-factors (/ n x))))))


Example 2:

(defun prime-factors (n)
    (unless (< n 2) (let ((x
  (loop as i from 2 to (sqrt n)
    thereis (if (= 0 (rem n i)) i)
    finally (return n))))
  (cons x (prime-factors (/ n x))))))


Example 3:

(defun prime-factors (n)
     (unless (< n 2) (let* (
  (first
     (loop as i from 2 to (sqrt n)
     thereis (if (= 0 (rem n i)) i)
     finally (return n)))
  (rest
     (prime-factors (/ n first))))
  (cons first rest))))


Example 4:

(defmacro flamx (f a)
 `((lambda (x) ,f) ,a))

(defun prime-factors (n)
    (unless (< n 2) (flamx
  (cons x (prime-factors (/ n x)))
  (loop as i from 2 to (sqrt n)
    thereis (if (= 0 (rem n i)) i)
    finally (return n)))))


For anyone who wants to quickly test the above examples to find out if
they are actually working code, here is a quick and easy test:

(mapcar #'prime-factors '(-100 -1 0 1 2 3 4 5 6 25 1000 1001 1009))

But in any case the purpose of posting these examples is to start a
discussion of coding style, especially coding style that conserves
screen space, and especially horizontal space.

From: Kent M Pitman
Subject: Re: Coding style
Date: 
Message-ID: <sfwwv28no1t.fsf@world.std.com>
··········@mailandnews.com (Software Scavenger) writes:

> I want to discuss Lisp coding style.
> [...]
> the purpose of posting these examples is to start a
> discussion of coding style, especially coding style that conserves
> screen space, and especially horizontal space.

I'm sure others will opine on this in much the same way as I would on
the issues of syntax rules per se, so I'm gonna skip that step and go
meta here.

Once I had a friend who liked kites and I wanted to make her a kite as
a present.  I really didn't know anything about kites and had to learn
all about it from books.  I *tried* to construct a model of the kite 
before making it and learned something important about wind-tunnels
that if I'd been more on the ball I would have learned years before
from wacthing Godzilla movies: scale matters.  I built my little kite and
put it in front of a fan, but it didn't fly right because the shape of 
the air coming out of the fan is not the same as the shape of the air in
the sky, and to some extent even if I could have controlled that I'd have
had the secondary problem that I read about somewhere that when you scale
down a windtunnel problem, the ratio of the size of the object to the size
of the air streams (and ultimately to the air molecules themselves) is
different and you get the wrong answers.  I'm told that commercial 
windtunnels are either built to scale or use a different gas that has
"smaller molecules" in order to compensate, or maybe they just wish they
did.  Ultimately, I scrapped the model and just built the kite.  
Fortunately, because it was a lot of work and I probably wasn't prepared
to repeat it, it did fly.

Anyway, I mention this little side story because your examples are very
small and so I don't think have the right properties to correctly address
the issues.  I think I'm personally pretty conservative about line width,
since I often work with telnet 80 column screens, but your examples left
big margins on my screen.  I think the problem is made artificially hard
if you insist on fitting everything to 40 or so columns because although
you're trying to keep things small, you're also eliminating many points
of flexibility that are statistically really available in real situations
rather than the contrived one you chose.  There's a certain average amount
of creep per paren level that I think is about 3-5 chars in worst case,
so that means in 80 columns, you should be able to get easily a dozen,
probably more, paren levels before you run into trouble.  And at some
point it's time to start a new function...

We, of course, *can* discuss the examples you raise, and I'm sure
people will, but I find that in production code, while there are
sometimes big jags in a specific case, code doesn't creep rightward
enough that this is a major problem other than just deciding what the
appropriate target width is; people I work with are pretty good about
working in whatever size they are given and it comes down to more of
an issue of knowing who likes what window size.

In the VERY FEW cases I've seen in my ENTIRE career where backing up was 
needed, I prefer the technique I've seen where someone does

    (blah blah
      (blah blah
        (blah blah
          ;------ begin reverse indentation to conserve space
 (foo
   (foo
     (foo)))
          ;------ end reverse indentation
          blah)))


However, most of the time I just don't find this necessary.  And truth be 
told, I'd have trouble constructing an example of where I *would* need to
do that.  That's why I'd rather see an example of where you think such
drastic action is *really* needed...
From: Bruce Hoult
Subject: Re: Coding style
Date: 
Message-ID: <bruce-55DB8F.20551207102001@news.paradise.net.nz>
In article <···············@world.std.com>, Kent M Pitman 
<······@world.std.com> wrote:

> I *tried* to construct a model of the kite 
> before making it and learned something important about wind-tunnels
> that if I'd been more on the ball I would have learned years before
> from wacthing Godzilla movies: scale matters.  I built my little kite and
> put it in front of a fan, but it didn't fly right because the shape of 
> the air coming out of the fan is not the same as the shape of the air in
> the sky, and to some extent even if I could have controlled that I'd have
> had the secondary problem that I read about somewhere that when you scale
> down a windtunnel problem, the ratio of the size of the object to the size
> of the air streams (and ultimately to the air molecules themselves) is
> different and you get the wrong answers.

In fact to get the same aerodynamic result you need to keep the Reynolds 
Number the same between the model and the real kite.  The Reynolds 
Number is proportional to the product of the size of the object and the 
airspeed, so -- quite counter-intuitively -- if your model was a tenth 
the size of the real kite then you'd need to test it in ten times the 
windspeed to find out if the aerodynamics were right.

-- Bruce
From: Tor Henrik Hanken
Subject: Re: Coding style
Date: 
Message-ID: <m3k7y7d7ul.fsf@localhost.localdomain>
[Software Scavenger]

| Example 1:
| 
| (defun prime-factors (n)
|   (unless (< n 2)
|     (let ((x (loop as i from 2 to (sqrt n)
|                    thereis (if (= 0 (rem n i)) i)
|                    finally (return n))))
|       (cons x (prime-factors (/ n x))))))

This is easy to read.  You can put in a few more newlines if you
want to save horizontal screenspace, like this:

(defun prime-factors (n)
  (unless (< n 2)
    (let ((x
	   (loop as i from 2 to (sqrt n)
		 thereis (if (= 0 (rem n i))
			     i)
		 finally (return n))))
      (cons x (prime-factors (/ n x))))))

(I would have used zerop and tail-recursion with LABELS too, but
this is besides the point.)

| Example 2:
| 
| (defun prime-factors (n)
|     (unless (< n 2) (let ((x
|   (loop as i from 2 to (sqrt n)
|     thereis (if (= 0 (rem n i)) i)
|     finally (return n))))
|   (cons x (prime-factors (/ n x))))))

I always expect an indentation after UNLESS, so I find the
misplaced LET fairly quickly.  It's more annoying than it is
confusing.  But then since UNLESS has an implicit PROGN there is
no way of knowing if the CONS is part the UNLESS body.  I have to
count the paretheses at the end of the LOOP, which is both
annoying and confusing.

| Example 3:
| 
| (defun prime-factors (n)
|      (unless (< n 2) (let* (
|   (first
|      (loop as i from 2 to (sqrt n)
|      thereis (if (= 0 (rem n i)) i)
|      finally (return n)))
|   (rest
|      (prime-factors (/ n first))))
|   (cons first rest))))

This time I confuse the variables FIRST and REST with the
accessors by the same names since I read them first, and it takes
a little more time to discover the misplaced LET*.  I like having
multiple namespaces, but I'd say the names of the variables
coupled with the screwy placement of LET* makes this example
slightly more confusing than the last one.  Also, "first" and
"rest" doesn't really provide any information about the contents
of these variables anyway.

| Example 4:
| 
| (defmacro flamx (f a)
|  `((lambda (x) ,f) ,a))
| 
| (defun prime-factors (n)
|     (unless (< n 2) (flamx
|   (cons x (prime-factors (/ n x)))
|   (loop as i from 2 to (sqrt n)
|     thereis (if (= 0 (rem n i)) i)
|     finally (return n)))))

This is a tough one.  Now I have the variable x coming out of
nowhere, and things doesn't happen in the same order that I'm
reading it.  My eyes go back and forth.  The variablenames are of
no help.  The added strain of reindenting the code properly in my
head makes it even more confusing, so this is by far the worst of
the four examples.

Many intelligent programmers have an aversion for redundancies
because they have no use for it.  They can read clever code
easily, so they enjoy compressing their code.  People have
different notions of what cleverness and elegance is all about,
and I think mine differs from yours.

Saving screenspace is not very important in my book.  I always
try to make my code easy to read, and I'm not afraid of being
verbose.  Being too verbose is much better than being obscure and
confusing.  Common Lisp is very well designed, so I always look
for conventional ways of doing things when I have to make choices
that seem arbitrary.  It's very comfortable, and part of the
reason why I prefer Common Lisp to less mature languages.  If I
still end up with weird-looking code, it's usually because I've
used a constuct in an unusual way, so I end up learning more
about how to use the different constructs and when they should be
applied.  As I learn more about the language I find myself
writing fewer lines of code as a side effect.

Rewrite your code when the lines get too long, it's probably
because you are being obscure anyway.  Your readers depend on
correct indentation, so making them count parentheses is not the
answer.  Creating abstractions is all about hiding certain parts
of the code from the reader, so you should be careful about what
you hide.  With macros you can hide anything, so you should be
extra careful. Macros should never introduce implicit variables
in the way FLAMX does, it's simply too difficult to read.  Macros
should be used to build abstractions that makes your code easier
to grasp, and never for pure textual compression.

-- 
Regards,

Tor Henrik Hanken
From: Kent M Pitman
Subject: Re: Coding style
Date: 
Message-ID: <sfw8zenihjt.fsf@world.std.com>
Tor Henrik Hanken <·········@copyleft.no> writes:

> (defun prime-factors (n)
>   (unless (< n 2)
>     (let ((x
> 	   (loop as i from 2 to (sqrt n)
> 		 thereis (if (= 0 (rem n i))
> 			     i)
> 		 finally (return n))))
>       (cons x (prime-factors (/ n x))))))
> 
> (I would have used zerop and tail-recursion with LABELS too, but
> this is besides the point.)

I agreed with most of your remarks, Tor, but not this one.

A tail-recursive implementation would have blown up with out-of-stack
in many implementations.  CL does not guarantee to do tail call
elimination, though implementations are permitted to, and you may be
used to using an implementation that does.  Still, for a computation
with potentially unbounded "tail depth" (to abuse a concept), I think
it's definitely bad style to select a mechanism that has such potential
problems over an algorithmically equivalent one that does not.

> | Example 2:
> | 
> | (defun prime-factors (n)
> |     (unless (< n 2) (let ((x
> |   (loop as i from 2 to (sqrt n)
> |     thereis (if (= 0 (rem n i)) i)
> |     finally (return n))))
> |   (cons x (prime-factors (/ n x))))))
> 
> I always expect an indentation after UNLESS, so I find the
> misplaced LET fairly quickly.  It's more annoying than it is
> confusing.  But then since UNLESS has an implicit PROGN there is
> no way of knowing if the CONS is part the UNLESS body.  I have to
> count the paretheses at the end of the LOOP, which is both
> annoying and confusing.

Put another way, "never put text inside a list to the left of its open
paren (nor even directly under) its open paren".  Otherwise, you utterly
defeat the ability of indentation to tell you any reliable information
at all and you reduce the reader to counting parens, something seasoned
Lisp programmers never actually do.

The other two violate this rule, too, so I just can't look at them.
(Meta-rule: Any practice that makes experienced programmers cringe or
throw up their hands when they look at your code should be pondered 
seriously...)  I'm going to continue to resist the urge to comment 
directly on them.

Some very good stuff here:

> Many intelligent programmers have an aversion for redundancies
> because they have no use for it.  They can read clever code
> easily, so they enjoy compressing their code.  People have
> different notions of what cleverness and elegance is all about,
> and I think mine differs from yours.
> 
> Saving screenspace is not very important in my book.  I always
> try to make my code easy to read, and I'm not afraid of being
> verbose.  Being too verbose is much better than being obscure and
> confusing.  Common Lisp is very well designed, so I always look
> for conventional ways of doing things when I have to make choices
> that seem arbitrary.  It's very comfortable, and part of the
> reason why I prefer Common Lisp to less mature languages.  If I
> still end up with weird-looking code, it's usually because I've
> used a constuct in an unusual way, so I end up learning more
> about how to use the different constructs and when they should be
> applied.  As I learn more about the language I find myself
> writing fewer lines of code as a side effect.
> 
> Rewrite your code when the lines get too long, it's probably
> because you are being obscure anyway.  Your readers depend on
> correct indentation, so making them count parentheses is not the
> answer.  Creating abstractions is all about hiding certain parts
> of the code from the reader, so you should be careful about what
> you hide.  With macros you can hide anything, so you should be
> extra careful. Macros should never introduce implicit variables
> in the way FLAMX does, it's simply too difficult to read.  Macros
> should be used to build abstractions that makes your code easier
> to grasp, and never for pure textual compression.

I've violated this last sentence once or twice, but not often enough to
think it's a bad rule.

Also, code should be written so that function names imply "what gets done"
even if not "how it gets done".  FLAMX implies none of this to me.  It might
as well stand for "fully locate all my xylophones".  As a rule, I just 
don't believe in obscure abbreviations.   A macro like "ASAP" for "as soon
as possible" in a parallel system might be ok because ASAP is an abbreviation
that occupies the status of a near-word in English.  Also, things that extend
(rather than fight with) the underlying language, such as the functions 
CHAR and CHDR (for "string first" and "string rest") in T (Yale Scheme) are
about at the limit of non-word status I'm willng to accept as good style
myself.  (Perhaps a little too cute...)  But largely I subscribe to the
"don't abbreviate" school of thought because it leads to code which is 
more easily maintainable by new people who may not be familiar with the 
subtlety of the code.  I cut CAR/CDR in the base language an exception since
I assume people have learned the base language, though at language design
time I'm not a big fan of words like this either; they're just so historical
and included in so many books that we adopted them into the language
IN SPITE of their being bad naming style, not because  we thought they were
to be emulated as a style.

Obscure abbreviations kind of remind me of when I was in tenth grade,
having just mastered high school algebra, and someone handed me a
calculus book. I flipped through it and looked at all the equations
and looked up to the person and said "looks just like the kind of
stuff I've been doing already. By the way, what's this squiggly line
[integral sign] do?"  Obscure abbreviations (to include integral sign)
have their place if there is large community agreement that the need
is great enough.  But they ought not be casually thrown in without the
consent of others who would read and work with them, since then they
serve to divide and irritate us, not to unite us, as a community.

Of course, all of this is opinion.  Style rules aren't hard and fast
things that never get broken.  But mostly I think they ought to be
treated as such by people who haven't enough experience with the
language to be sure when it's time to break them.  What's really
important is getting to the point where one understands and
appreciates the motivation behind the style rule; that knowledge will
tell the programmer when it's reasonable to violate it.  Often style
rules are safety zones around more subtle problems the conditions of which
are trickier to explain to a novice.
From: Thomas F. Burdick
Subject: Re: Coding style
Date: 
Message-ID: <xcvitdr2g0n.fsf@famine.OCF.Berkeley.EDU>
··········@mailandnews.com (Software Scavenger) writes:

> I want to discuss Lisp coding style.  In the examples below of a
> prime-factors function, the first example is closest to the canonical
> Lisp coding style, but this style has problems such as higher
> incidence of word-wrap when viewing in smaller windows.

I've never found a function where I needed the body to be at column
40.  I've thought I did a couple of times, but the next day it was
obvious how I could refactor the problem to get a reasonable level of
indentation.  I'm sure such functions do exist, because if I were to
assert that none did, someone would show me up, I'm sure, but why
change coding style to accommodate a tiny minority of the work you'll
be doing.  In addition to everything else you sacrifice by eschewing
standard indentation style, you're actively avoiding that red flag of
"oh crap, I'm too far to the right to type anything ... maybe I'm
doing something wrong", which I find quite helpful.

> For the 4th example, I use a macro, flamx, to support a style which
> might seem slightly awkward for this particular example but has some
> potential for neater code in other cases.  The name flamx is an
> abbreviation for funcall-lambda-x.  This macro is inspired by the fact
> that this style of coding would make frequent use of idioms such as
> ((lambda (x) (...)) ...) and such frequent use implies a reason to
> shorten and/or neaten the syntax.  Other macros might supplement it,
> such as flamxy, etc.  But regardless of the merits of flamx etc., it's
> also worthwhile to discuss the merits in general of using macros to
> support coding styles.

I find ((lambda (x) ...) ...) a great way to obfuscate code, but not a
very generally useful technique.  LET is good because you introduce
variables next to where they get their values, and evaluation happens
left-to-right.  If you ever have a FLAMX contaning another FLAMX,
evaluation is going to jump all over the place.  Other than that, I
can't stand control structures with confusing names, or macros that
introduce variables with magical names.  If I want to nest them, I'd
need to go:
 (flamx
   (let ((y x))
     (flamx ...))
   ...)
Not to mention that I might want to name my variable something more
descriptive than X.  If you *really* like doing ((lambda (x)...)...),
and *really* don't like typing, why don't you just use
 (defmacro l (ll &body forms)
   `(lambda ,ll ,@forms))
Then you can do ((L (x) ...) ...) (I still say ick).

> But in any case the purpose of posting these examples is to start a
> discussion of coding style, especially coding style that conserves
> screen space, and especially horizontal space.

Ordinary lisp style already conserves screen space.  A layer of parens
generally introduces 1-3 spaces.  Which means that if your line is
starting at column 40, you've probably got at least 14 layers of
nesting.  Ick.  Nesting LOOP is a good way to waste screen space, but
then LOOP is weird and doesn't look like lisp code.  Even there,
though, you don't have to trade much vertical space for horizontal:
 (loop
  for ...
  do
   (loop ...))
And you can always use DO if it really bugs you.
From: Marco Antoniotti
Subject: Re: Coding style
Date: 
Message-ID: <y6cadz3uqvm.fsf@octagon.mrl.nyu.edu>
··········@mailandnews.com (Software Scavenger) writes:

> I want to discuss Lisp coding style.  In the examples below of a
> prime-factors function, the first example is closest to the canonical
> Lisp coding style, but this style has problems such as higher
> incidence of word-wrap when viewing in smaller windows.

Let's start with the Prime Directive of Lisp Programming.

Thou shal not have other editor than Emacs with auto-fill-mode on and
fill-colum set between 70 and 80.


> 
> 
> Example 1:
> 
> (defun prime-factors (n)
>   (unless (< n 2)
>     (let ((x (loop as i from 2 to (sqrt n)
>                    thereis (if (= 0 (rem n i)) i)
>                    finally (return n))))
>       (cons x (prime-factors (/ n x))))))

This is good.

> 
> 
> Example 2:
> 
> (defun prime-factors (n)
>     (unless (< n 2) (let ((x
>   (loop as i from 2 to (sqrt n)
>     thereis (if (= 0 (rem n i)) i)
>     finally (return n))))
>   (cons x (prime-factors (/ n x))))))

Emacs will not let you type code like this if not seriously tweaked (a
capital sin, of course), hence this indentation is classified as bogus.


> Example 3:
> 
> (defun prime-factors (n)
>      (unless (< n 2) (let* (
>   (first
>      (loop as i from 2 to (sqrt n)
>      thereis (if (= 0 (rem n i)) i)
>      finally (return n)))
>   (rest
>      (prime-factors (/ n first))))
>   (cons first rest))))

The same applies in this case.

> 
> Example 4:
> 
> (defmacro flamx (f a)
>  `((lambda (x) ,f) ,a))
> 
> (defun prime-factors (n)
>     (unless (< n 2) (flamx
>   (cons x (prime-factors (/ n x)))
>   (loop as i from 2 to (sqrt n)
>     thereis (if (= 0 (rem n i)) i)
>     finally (return n)))))

Not to speak of this one.

As punishment for having proposed these indentation styles, you have
to write a Python (tllotbafir) interpreter in INTERCAL.

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'.
From: Erik Naggum
Subject: Re: Coding style
Date: 
Message-ID: <3211489735193683@naggum.net>
* Software Scavenger
| I want to discuss Lisp coding style.

  In these times of war, I think that is a wise choice.  Nothing unites
  people against their common enemies like discussing (bad) coding styles.

| In the examples below of a prime-factors function, the first example is
| closest to the canonical Lisp coding style, but this style has problems
| such as higher incidence of word-wrap when viewing in smaller windows.

  If you have a handicap that requires to you to use very large fonts, I
  think you should say so up front so we know the context of your needs.
  If you only have smaller windows, you use the wrong operating system or
  even hardware for your needs, and should not receive any sympathy. Well,
  perhaps a gift certificate for a hardware upgrade, but nothing about your
  coding style should receive any sympathy.

| The 2nd example is a style intended to reduce usage of screen real estate.

  If screen real estate is actually a _problem_, the solution is _not_ to
  fiddle with coding styles, but to choose smaller or narrower fonts and
  find ways to get the clutter out of your windows.  E.g., the Microsoft
  Windows paradigm is that you have no virtual screen estate, and cannot
  switch between workspaces.  This frustrated the hell out of me when I had
  to use that abominable luser interface.  A billion small pop-up windows
  would show up and demand attention like I lived to respond to some kind
  of moronic psychological test.  With X Windows, I use vtwm, which lets me
  have a large number of work spaces where I can have a few large windows
  with lots of real information, and switch between _complete_ contexts
  instead of being bothered by noise from other contexts all the time.  I
  realize that beign able to concentrate for a sustained period of time on
  a single task at a time is a negative personality characteristic in these
  days of animated, if not agitated, banner ads even in the New York Times
  and self-refreshing web pages that not only crash your browser, but fail
  to position themselves where they were the last time you looked.  None of
  these issues may of course be related to _your_ screen real estate issue,
  but if they are, please considering fixing the real problem.

| The unless/let line is indented instead of having all the lines below it
| indented, as one easy way to reduce overall horizontal size.

  How much manual effort do you put into these stunts?  Indentation and
  coding styles should be invisible and effortless to produce and read.
  The more effort you put into it, the more effort goes into reading it,
  and you achieve your goals at a very high cost.  Back in the 70's, there
  were a lot of interest in "syntax-directed editors", but as developers
  have universally come to trust Emacs programming modes (and those who do
  not know Emacs are merely doomed to reinvent it badly), there is no need
  at all to do indentation manually.  If you ever find that you have to do
  that, you are doing something wrong.

| The 3rd example is a compromise to minimize horizontal size and maximize
| readability.

  You maximize readability by doing what everybody else does.  This also
  includes not inventing your own conditionals because you are dissatisfied
  with the indentation of cond or have a personal hangup with progn that
  makes you do something fantastically ugly and unreadable that causes you
  to lose friends and the respect of a whole community when you elevate
  your silly aesthetics to abject fanaticism.  People have been known to go
  off and invent their own _languages_ simply because they had a problem
  with indentation in other languages.

| But regardless of the merits of flamx etc., it's also worthwhile to
| discuss the merits in general of using macros to support coding styles.

  Hardly.  Anything you do with coding styles should _reduce_ the cognitive
  load on the reader.  If it does not do that, it is _bad_ to mess with the
  coding styles.  Cognitive load is not a subjective thing, but it has some
  _personal_ qualities.  That is, it is not hard to figure out what kind of
  factors are involved, but precisely which values to assign to each factor
  may vary somewhat from person to person.  E.g., you have basically done
  what another "coding style freak" has done previously: Break a lot of
  good stuff, consensus, community goodwill, and even the basic trust in
  his sanity in order to get a single and fundamentally silly readability
  factor only slightly improved at such costs that it is obvious that it
  never was a _rational_ thing to do.

| But in any case the purpose of posting these examples is to start a
| discussion of coding style, especially coding style that conserves
| screen space, and especially horizontal space.

  The presumption that these are valid concerns also need discussion.  I
  think that qua concerns, they are completely misplaced.  If you want to
  conserve space so badly, using a language that has longer operator names
  than a couple characters is probably a bad idea.  If you want to cut down
  on the compounded indentation, you can reduce the default indentation
  from 2 to 1.  If you think you have no use for indentation, you can try
  to cut it down to 0, too.

  As for your particular code, I think it displays an incredibly ugly abuse
  of loop features right off the bat and I had a hard time following your
  code.  The thereis clause means you are looking for something and
  returning it, but you are looking for something and returning something
  else in an ugly punning operation.  Also, returning a value from the loop
  form means you return a counter-interintuitive sentinel value and that
  you need to guard against impossible values because of this.  Concern
  over the use of horizontal space by this function is just plain silly.

(defun prime-factors (n)
  (unless (< n 2)
    (let ((x (loop as i from 2 to (sqrt n)
                   thereis (if (= 0 (rem n i)) i)
                   finally (return n))))
      (cons x (prime-factors (/ n x))))))

  Consider this rewrite, one possible among many:

(defun prime-factors (n)
  (loop for i from 2 to (isqrt n)
      if (= 0 (mod n i))
      return (cons i (prime-factors (/ n i)))
      finally (return (list n))))  

  Note the use of isqrt to get an integer root, which would be important
  when asking for the prime factors of large numbers lest the floating
  point value likely returned by sqrt not capture the exact root value.
  Note also that sqrt is defined to return a rational or a _single-float_
  value, which is _really_ bad mathematically -- if it were not for the
  staggeringly naive way you search the prime space, you would run into
  serious accuracy problems with completely bogus comparisons between the
  integer i and the single-float (sqrt n), but it should take so long to
  run into this problem that you most probably would not actually use your
  algorithm on numbers with large prime factors, but I could be wrong about
  how soon you will run into a problem.

///
From: Johan Kullstam
Subject: Re: Coding style
Date: 
Message-ID: <m27ku6iaj5.fsf@euler.axel.nom>
Fernando <···@wanadoo.es> writes:

> On Mon, 08 Oct 2001 00:28:59 GMT, Erik Naggum <····@naggum.net> wrote:
> 
> 
> >  If screen real estate is actually a _problem_, the solution is _not_ to
> >  fiddle with coding styles, but to choose smaller or narrower fonts and
> >  find ways to get the clutter out of your windows.  E.g., the Microsoft
> >  Windows paradigm is that you have no virtual screen estate, and cannot
> >  switch between workspaces.  This frustrated the hell out of me when I had
> >  to use that abominable luser interface. 
> 
> There are virtual screen managers for windows.

yes, but you still have to service the pop-up windows stealing your
focus.

-- 
J o h a n  K u l l s t a m
[········@mediaone.net]
"Millenium hand and shrimp" -- Foul Ole Ron
From: Louis Theran
Subject: Re: Coding style
Date: 
Message-ID: <B7E8F0E2.1DA6%theran@cs.umass.edu>
On 10/8/01 8.27, in article ··············@euler.axel.nom, "Johan Kullstam"
<········@ne.mediaone.net> wrote:

> Fernando <···@wanadoo.es> writes:
> 
>> On Mon, 08 Oct 2001 00:28:59 GMT, Erik Naggum <····@naggum.net> wrote:
>> 
>> 
>>>  If screen real estate is actually a _problem_, the solution is _not_ to
>>>  fiddle with coding styles, but to choose smaller or narrower fonts and
>>>  find ways to get the clutter out of your windows.  E.g., the Microsoft
>>>  Windows paradigm is that you have no virtual screen estate, and cannot
>>>  switch between workspaces.  This frustrated the hell out of me when I had
>>>  to use that abominable luser interface.
>> 
>> There are virtual screen managers for windows.
> 
> yes, but you still have to service the pop-up windows stealing your
> focus.

When I used X, modal dialogs (or even modeless ones) were a disaster, since
they couldn't _get_ focus unless I moused over them, and then the focus was
never on the right part of the dialog.  Thus using and disposing of one was
always a major pain.

My solution was to avoid as much as possible any application that would ever
throw one up, which is somewhat limiting.  X truly is the non-graphical GUI.
:)

^L
From: Johan Kullstam
Subject: [OT] random GUI gripes (was Re: Coding style)
Date: 
Message-ID: <m3het7a6d9.fsf_-_@sysengr.res.ray.com>
Louis Theran <······@cs.umass.edu> writes:

> On 10/8/01 8.27, in article ··············@euler.axel.nom, "Johan Kullstam"
> <········@ne.mediaone.net> wrote:
> 
> > Fernando <···@wanadoo.es> writes:
> > 
> >> On Mon, 08 Oct 2001 00:28:59 GMT, Erik Naggum <····@naggum.net> wrote:
> >> 
> >> 
> >>>  If screen real estate is actually a _problem_, the solution is _not_ to
> >>>  fiddle with coding styles, but to choose smaller or narrower fonts and
> >>>  find ways to get the clutter out of your windows.  E.g., the Microsoft
> >>>  Windows paradigm is that you have no virtual screen estate, and cannot
> >>>  switch between workspaces.  This frustrated the hell out of me when I had
> >>>  to use that abominable luser interface.
> >> 
> >> There are virtual screen managers for windows.
> > 
> > yes, but you still have to service the pop-up windows stealing your
> > focus.
> 
> When I used X, modal dialogs (or even modeless ones) were a disaster, since
> they couldn't _get_ focus unless I moused over them, and then the focus was
> never on the right part of the dialog.  Thus using and disposing of one was
> always a major pain.
> 
> My solution was to avoid as much as possible any application that would ever
> throw one up, which is somewhat limiting.  X truly is the non-graphical GUI.
> :)

it is not the fault of X.  X is very low level and is only a display
driver.  for some window managers and some toolkits this is true.  i
understand your complaint and it is a large part of the reason i am
using the fsf emacs and not xemacs.  those dialog boxen do suck.

however, i am using X and use the sawfish window manager (obLisp: it
has a lisp (fortunately a lisp2 and not a scheme like guile, but,
alas, not common-lisp) configuration language).  when i use gnome
applications, they can launch dialog boxes with a text area.  focus is
given to the dialog box despite the mouse pointer being nowhere the
box.  i can type in the text window without problems.

my biggest gripe with the windows dialogs is that some random
background task would pop one of them in my face and require me to
service it.  e.g., i am typing away in ms-word and suddenly a popup
appears to inform me of new mail.  i lose 20 characters worth of
typing and lose my train of thought.  sometimes i hit return on an
important dialog and inadvertantly choose to do the wrong thing.

-- 
J o h a n  K u l l s t a m
[········@ne.mediaone.net]
sysengr
From: Michael Livshin
Subject: Re: [OT] random GUI gripes (was Re: Coding style)
Date: 
Message-ID: <s3itdn4hrf.fsf@yahoo.com.cmm>
[ more offtopic, sorry ]

Johan Kullstam <········@ne.mediaone.net> writes:

> it is not the fault of X.  X is very low level and is only a display
> driver.  for some window managers and some toolkits this is true.  i
> understand your complaint and it is a large part of the reason i am
> using the fsf emacs and not xemacs.  those dialog boxen do suck.

useless factoid #0: you can use XEmacs without dialog boxes, it's
configurable.  I do.

> however, i am using X and use the sawfish window manager (obLisp: it
> has a lisp (fortunately a lisp2 and not a scheme like guile, but,
> alas, not common-lisp) configuration language).

useless factoid #1: rep (the Lispy language in Sawfish) is a Lisp1.

> my biggest gripe with the windows dialogs is that some random
> background task would pop one of them in my face and require me to
> service it.  e.g., i am typing away in ms-word and suddenly a popup
> appears to inform me of new mail.  i lose 20 characters worth of
> typing and lose my train of thought.  sometimes i hit return on an
> important dialog and inadvertantly choose to do the wrong thing.

and you can't even fault the designers Outlook (or whatever it is) for
that, really.  I wish the various GUI-infrastructure designers have
thought about user<->desktop interaction as a _protocol_ and designed
it accordingly.  but no, they left it to the apps to sort out in the
dark.

-- 
programmer, n:
        A red eyed, mumbling mammal capable of conversing with inanimate
        monsters.
From: Janis Dzerins
Subject: Re: [OT] random GUI gripes (was Re: Coding style)
Date: 
Message-ID: <87itdnjunp.fsf@asaka.latnet.lv>
Johan Kullstam <········@ne.mediaone.net> writes:

> however, i am using X and use the sawfish window manager (obLisp: it
> has a lisp (fortunately a lisp2 and not a scheme like guile, but,
> alas, not common-lisp) configuration language).

sawfish uses rep, which I haven't heard had been changed into lisp2.

-- 
Janis Dzerins

  Eat shit -- billions of flies can't be wrong.
From: Kaz Kylheku
Subject: Re: Coding style
Date: 
Message-ID: <oi0x7.61371$ob.1508828@news1.rdc1.bc.home.com>
In article <····················@cs.umass.edu>, Louis Theran wrote:
>When I used X, modal dialogs (or even modeless ones) were a disaster, since
>they couldn't _get_ focus unless I moused over them, and then the focus was
>never on the right part of the dialog.  Thus using and disposing of one was
>always a major pain.

Note that the focus behavior is controlled by the window manager. 
A flexible window manager lets you configure  whether you want
click-to-focus or focus-follows-pointer.

There are many window managers these days with a myriad behaviors.
From: Kenny Tilton
Subject: Re: Coding style
Date: 
Message-ID: <3BC1C150.C17F3F32@nyc.rr.com>
Another fix: I finally broke down and hooked up a second monitor to my
dual-monitor video card, lovin't it.

kenny
clinisys

Fernando wrote:
> 
> There are virtual screen managers for windows.
From: Tim Bradshaw
Subject: Re: Coding style
Date: 
Message-ID: <ey3r8sel51y.fsf@cley.com>
* frr  wrote:

> This is a proof that even professional developers don't get their priorities
> right when buying hardware: when you spend 8 hours a day (or even more)
> working with a computer, you spend them staring a the monitor, not the
> processor or the ram. Get yourself a _good_ monitor and forget the
> indentation.

Actually, memory matters too.  If you have a big monitor and a virtual
window manager (like Erik, I use one of the virtual twm derivatives),
you can end up with a lot of contexts with a lot of windows per
context, and you don't want changing between them to cause the machine
to thrash for more than half a second.  Memory is also so cheap that
there's really no point in having a machine with less than 512Mb or
something unless you physically can't fit that much (my laptop has
320 (I think as much as it can have), the 256Mb extra I put in was L88
- for expensive laptop memory, desktop memory must be very much
cheaper).

If you're writing C++ you also need an enormously fast machine with an
amazing disk subsystem because builds are *extremely* demanding, and
you want to get more than one done a day, but Lisp development
environments are much less demanding than C++ ones.

--tim