Arc Forumnew | comments | leaders | submitlogin
3 points by absz 6022 days ago | link | parent

Not quite—from Bogart's post, it sounds like they want to be able to write (= eval my-magic-fn), and then (+ a b) would be passed through the new eval too. This would be interesting; I've been thinking about similar things.


3 points by eds 6022 days ago | link

Ok, so you can't just redefine 'eval, you need to redefine 'eval and have MzScheme use that function on the Scheme side of things as well.

It looks like the 'arc-eval function is basically the one you want to redefine, since that is the one that is called inside the definition of 'tl2. In fact, the definition of 'eval is exactly the same as 'arc-eval except 'eval calls 'ac-denil on its arguments before compiling them. So basically what you would want to do would be to look up the value of the arc-side eval function and call that instead of hard coding a call to 'arc-eval. Right?

-----

6 points by absz 6022 days ago | link

It sounds like that should work: change the xdef of eval to

  (xdef 'eval (lambda (expr) (arc-prim-eval (ac-denil expr))))
, and then change arc-eval to

  (define (arc-prim-eval expr)
    (eval (ac expr '()) (interaction-environment)))
  
  (define (arc-eval expr) 
    ((eval '__eval) expr))
. The xdef should come soon enough to prevent something from calling a non-existent eval. Then, in Arc, you should be able to do

  (redef eval (expr)
    (prn " - debug - " expr)
    (old expr))
or whatever. Let me test that...

...

...yes, this works! Well, almost. I didn't really test it, but (a) ordinary things seem to get evaluated fine, and (b) the message is printed. It doesn't seem to hit everything in a macro-expansion, but I can't tell whether or not it should. For instance, I get (output reformatted for clarity)

  arc> (mac do+ (a b) `(do (prn ,a) (prn ,b) (+ ,a ,b)))
   - debug - (mac do+ (a b) `(do (prn ,a) (prn ,b) (+ ,a ,b)))
   - debug - (input-history-update
               (mac do+ (a b) `(do (prn ,a) (prn ,b) (+ ,a ,b))))
   - debug - (output-history-update
               (quote #(tagged mac #<procedure>)))
  #3(tagged mac #<procedure>)
  arc> (do+ 1 2)
   - debug - (do+ 1 2)
  1
  2
   - debug - (input-history-update (quote (do+ 1 2)))
   - debug - (output-history-update (quote 3))
  3
. (Of course, its output didn't have extra line breaks and had quasiquote instead of `, etc.) I feel like it should print

   - debug - (do (prn 1) (prn 2) (+ 1 2))
too.

<EDIT>

The problem is that ac-mac-call calls ac directly so that it can pass the current environment as a second argument. Perhaps arc-eval should take an optional environment argument too? But that would clutter things unnecessarily on the Arc side... anyway, the point is, after looking at it for all of five minutes, macros are tricky. (And I haven't even looked at ac-macex yet...) For instance, a simple test:

  arc> (nil 1 2)
  Error: "string-ref: index 0 out of range for empty string"
  arc> (redef eval (expr)
         (if (and (cons? expr) (~car expr))
           (cdr expr)
           (old expr)))
  #<procedure: eval>
  arc> (nil 1 2)
  (1 2)
  arc> (mac donil (a b) `(nil ,a ,b))
  #3(tagged mac #<procedure>)
  arc> (donil 1 2) ; Should return (1 2), but:
  Error: "string-ref: index 0 out of range for empty string"
</EDIT>

The downside is that, if it isn't slow now, it might well prohibit certain optimizations (though reading Steve Yegge's recent talk makes me think that I might well be wrong). Is this worth pushing on Anarki?

-----