merits of Lisp vs Python

Ken Tilton kentilton at gmail.com
Thu Dec 14 02:52:27 EST 2006



Ken Tilton wrote:
> 
> 
> Ken Tilton wrote:
> 
>>
>>
>> Paul Rubin wrote:
>>
>>> Ken Tilton <kentilton at gmail.com> writes:
>>>
>>>> don't know. The point is, we need code (not just data) in defskill
>>>> (apologies for nasty formatting):
>>>
>>>
>>>
>>>
>>> Man that whole thing is messy.
> 
> 
> I do not see much difference, except that the character count is 25% 
> less in the macro version:
> 
> (defskill absolute-value
>     (title "Absolute Value")
>   (annotations
>    "Absolute value of #strn# is the 'distance' of #strn# from zero."
>    "Absolute value is always zero or positive: #str|n|=n#, and 
> #str|-n|=n#.")
>   (hints
>    "Some examples: #str|+42|=42#, #str|-42|=42#, and #str|0|=0#."
>    "To get the absolute value of a number such as #signed-value#, we 
> simply drop any minus sign.")
>   (reverse
>    (ensure-cloning resx
>      (make-instance 'mx-number
>        :value (loop with op1 = (car opnds)
>                   with log = (max 1 (ceiling (log (abs (value op1)) 10)))
>                   for n = (* (signum (value op1))
>                             (+ 2 (random (expt 10 log))))
>                   when (/= n (value op1))
>                   return n)
>        :representation (representation resx)))))
> 
> (defmethod skill-title ((tf-id (eql 'absolute-value)))
>   (list "absolute value"))
> 
> (defmethod skill-annotations ((tf-id (eql 'absolute-value)))
>   (list "absolute value of #strn# is the 'distance' of #strn# from zero."
>     "absolute value is always zero or positive: #strn=n#, and #str-n=n#."))
> 
> (defmethod skill-hints ((tf-id (eql 'absolute-value)))
>   (list "some examples: #str+42=42#, #str-42=42#, and #str0=0#."
>     "to get the absolute value of a number such as #signed-value#, we 
> simply drop any minus sign."))
> 
> (defmethod tf-reverse ((id (eql 'absolute-value)) resx opnds)
>   (declare (ignorable resx opnds))
>   (ensure-cloning resx
>     (make-instance 'mx-number :value
>       (loop with op1 = (car opnds) with log = (max 1 (ceiling (log (abs 
> (value op1)) 10))) for n =
>             (* (signum (value op1)) (+ 2 (random (expt 10 log)))) when 
> (/= n (value op1)) return n)
>       :representation (representation resx)))))

Even better. That "(car opnds)" up there is an unpleasant hard-coding 
that must align with how operands get recorded by the transformation 
code that built the TF log entry that is being reversed. Ewww. What the 
first opnds is supposed to be is the signed value of which the absolute 
vale is being taken. Wouldn't it be nice to just say "signed-value"?:

We can just look at the reverse option now:

(defskill absolute-value
     ....
   (reverse (signed-value)
     (ensure-cloning resx
       (make-instance 'mx-number
         :value (loop with svn = (value signed-value)
                    with log = (max 1 (ceiling (log (abs svn) 10)))
                    for n = (* (signum svn)(+ 2 (random (expt 10 log))))
                    when (/= n svn)
                    return n)
         :representation (representation resx)))))

A major point here is that the above (trust me) is the exact syntax of 
FLET and LABELS in Lisp. The big hobgoblin (and precise objection 
offered by GvR) is that macro use yields unrecognizably (in this case) 
Lisp code. But we love lisp and its patterns, and one ethic for macro 
writers is to follow those patterns in extending the language.

Maybe that poor horse can be allowed to rest in peace, or must we flog 
it some more for youse people?

Now operands and results get tagged at TF time with symbols. How on 
earth does a local variable of the same name get bound to the operand 
logged at TF time? Easy, look it up. But where is the code? Not outside 
the function; the caller of the reversal function does not know which 
logged operand to pass in which function parameter position. So the 
lookup code has to be in the reverse function source, like this:

(defmethod tf-reverse ((id (eql 'absolute-value)) tf drv
                         &aux (opnds (drv-opnds tf drv)))
   (declare (ignorable opnds))
   (let ((signed-value (tf-drv-lookup tf drv 'signed-value))) <=====
     (loop for resx in (results drv) do
           (ensure-cloning resx
             (make-instance 'mx-number :value
               (loop with svn = (value signed-value)
                     with log = (max 1 (ceiling (log (abs svn) 10)))
                     for n = (* (signum svn)
                                (+ 2 (random (expt 10 log))))
                     when (/= n svn) return n)
               :representation (representation resx))))))

WordPerfect says thats 405 characters, 64 words vs 241/38 for the actual 
source.

Now in this case I happen to be just starting on this mechanism, so i do 
not really have 42 I do not have to change, but I am about to start 
churning these things out and I expect refinements to continue.

No problem.

ken

-- 
Algebra: http://www.tilton-technology.com/LispNycAlgebra1.htm

"Well, I've wrestled with reality for thirty-five
years, Doctor, and I'm happy to state I finally
won out over it." -- Elwood P. Dowd

"I'll say I'm losing my grip, and it feels terrific."
    -- Smiling husband to scowling wife, New Yorker cartoon



More information about the Python-list mailing list