merits of Lisp vs Python

Ken Tilton kentilton at gmail.com
Wed Dec 13 23:44:26 EST 2006



greg wrote:
> Ken Tilton wrote:
> 
>> pps. How would Python do this?
> 
> 
> Here's one way it could look:
> 
>   defskill("absolute-value",
>     title = "Absolute Value",
>     annotations = [
>      "Take the absolute value of #op#.",
>      "The vertical bars around #op# mean 'the absolute value of' #op#.",
>      "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 = [
>      "What do those vertical bars around #op# mean?",
>      "Have you learned about 'absolute value'?",
>      """Absolute value can be thought of as the 'distance' of a value from
>         zero on the number line, and distance is always positive.""",
>      "The rule is:#str|-n|=|n|##str=n#.  Can you apply that to #op#?",
>      "Some examples: #str|+42|=42#, #str|-42|=42#, and #str|0|=0#.",
>      """To get the absolute value of a number such as #op#, we simply drop
>         any minus sign."""
>     ]
>   )
> 
>  > Is it possible to avoid committing to an
>  > implementation mechanism?
> 
> The defskill function could do just about anything with this.
> Here's one possibility:
> 
>   skills = {}
> 
>   class Skill:
>     pass # fill in whatever methods you need here
> 
>   def defskill(name, title, annotations, hints):
>     skill = Skill()
>     skill.title = title
>     skill.annotations = annotations
>     skill.hints = hints
>     skills[name] = skill
> 
> This gives you a dictionary of Skill instances indexed by name,
> each one having a title and lists of annotation and hint strings.
> The rest of the system can process this however required.

Ok, not too bad, not much syntax in there. But now I have a tougher 
requirement for you, which I noticed only after posting. (I tried 
running the damn thing and it whined about not knowing how to "reverse" 
absolute-value (to clone one problem into a similar problem).) A 
reversal must be able to yield any given a result, and sometimes must 
use given operands already settled on by the larger reversing algorithm. 
In the simpler case, to reverse absolute-value with result 42 we produce 
either |42| or |-42|. In the more complicated case, the multiply-literal 
  reverser may discover 6 is an operand and 42 is the result (meaning it 
does no randomization, it just supplies the (* 6 7) reversal. Why am I 
telling you all this? I don't know. The point is, we need code (not just 
data) in defskill (apologies for nasty formatting):

(defmacro defskill (id &body skill-info)
   `(progn
      ,@(loop with sub-id = id
              for (q . q-def) in skill-info
              collecting (ecase q
                           ((title annotations hints)
                            `(defmethod ,(intern (conc$ 'skill- q)) 
((tf-id (eql ',sub-id)))
                               (list , at q-def)))
                           (reverse
                            `(defmethod tf-reverse ((id (eql ',sub-id)) 
resx opnds)
                               (declare (ignorable resx opnds))
                               , at q-def))))))

--------------- (Abbreviated) Example.... ------------------------------

(defskill absolute-value
     (title "Absolute Value")
   (annotations
    "Absolute value is always zero or positive: #str|n|=n#, and 
#str|-n|=n#.")
   (hints
    "What do those vertical bars around #op# mean?")
   (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)))))

-------------- Producing.... ---------------------------------


(progn (defmethod skill-title ((tf-id (eql 'absolute-value))) (list 
"absolute value"))
        (defmethod skill-annotations ((tf-id (eql 'absolute-value)))
          (list "absolute value is always zero or positive: #strn=n#, 
and #str-n=n#."))
        (defmethod skill-hints ((tf-id (eql 'absolute-value)))
          (list "what do those vertical bars around #op# mean?"))
        (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)))))

How close can Python get when code is involved? The reverse function 
signature is fixed, so can lambda help?

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