simp.lisp



On Jan 24, 2008 3:45 PM, Rupert Swarbrick <rupert.swarbrick at lineone.net>
wrote:

> I really would argue for reformatting though: code like this:
>
> (defmfun simplifya (x y)
>  (cond ((atom x) (cond ((and (eq x '$%pi) $numer) %pi-val) (t x)))
>        ((not $simp) x)
>  ...
>
> is rather difficult to parse by eye and contains a lot of functionality
> on each line, the second being a problem with diff-based version
> control systems.
>

I suppose you'd prefer something like:

(defmfun simplifya (x y)
  (cond
     ((atom x)
      (cond
         ((and (eq x '$%pi)
               $numer
          )
          %pi-val
         )
         (t
          x
         )
      )
     )

I *detest* code formatted like this (and have had to read a bunch of it in a
Java environment).  It has so much whitespace added that you can't see the
big picture.

But perhaps you just want:

(defmfun simplifya (x y)
  (cond ((atom x)
        (cond ((and (eq x '$%pi) $numer)
               %pi-val)
              (t x)))
                      ...

Though I simply dislike this much whitespace (don't detest it), I still find
the original version easier to read, because one simple idea (atoms simplify
to themselves except for %pi under $numer) is expressed in one simple line.

 Do you see what I mean about different taste in formatting?


> Yikes! That's quite impressive! But seriously, I think there are two
> possibly conflicting priorities here. One is absolute: there should be
> no regressions. However, if we can, Ithink we'd gain a vast amount by
> refactoring and combining this sort of code: the whole tree would
> slowly get easier to read and, more importantly, understand enough to
> fix bugs in.


I understand the argument (after all, it's why I wrote opers in the first
place -- before that, code looked like (simplifya (list '(mplus) a b) nil) )
but alas most of the difficulty in understanding the code is because the
logic is complicated, there are lots of global variables, etc.


> I completely agree about the good taste comment. Although I think there
> are some things that are objective: when writing new code avoid gotos
> maybe :) (Yes, I know that the stuff I'm moaning about was probably
> written in the '70s when e.g. loop didn't exist)


If the choice is between the weird complexities of loop and the difficulty
of understanding goto, I'm not sure I'd prefer loop consistently. But most
of the goto's in simp probably can't be expressed by loop in any
straightforward way anyway. Multiple mutually recursive functions would
probably be required; and if you want to avoid global variables (certainly a
good idea in general), you'd probably also have long variable lists....  I'm
not sure what a cleaner version would look like.  And general simplification
is one of the few places where efficiency might actually matter even
today....

> I'd recommend you take some *specific* bugs that have been documented
> > and fix them as locally as possible (i.e. don't rewrite everything).
> > For example, making sure that 2/sqrt(2) simplifies to sqrt(2) without
> > breaking anything else.
>
> I sort of agree, and sort of don't. (Sorry!) Firstly, I agree that
> there's absolutely no point in changing code just for the fun of it.
> However, I'm not so sure that every change needs to "add
> functionality". The mere existence of ancient bugs in the sf tracker
> suggests that some of them are fundamentally hard to fix with the
> current architecture, which is understood by maybe only a couple of
> people (you and Richard Fateman maybe?).
>

Changing "architecture" is quite a different matter from making local
changes which replace m+ by add and goto by loop. And an architectural
change would be an especially good reason to first have a good test suite.

The general simplifier, by the way, dates from before the Macsyma/Maxima
itself, to a fellow named Korsvold.

               -s