Subject: Re: Coding style From: Erik Naggum <erik@naggum.net> Date: Mon, 08 Oct 2001 00:28:59 GMT Newsgroups: comp.lang.lisp 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. ///