Arc Forumnew | comments | leaders | submitlogin
1 point by almkglor 5977 days ago | link | parent

Note that redefinition using (p!until age) syntax is still possible in Arc using 'defcall and if you predeclare the private variables.

For instance, consider this:

  (deftype foo (x)
    (private y z)
    (meth niaw ()
      (do-something x y z))
    (meth arf (something)
      (do-something-else something x y z)))
  =>
  (let methods
       (table
         ; lambda lifted!
         'niaw
         (fn (x y z)
             (do-something x y z))
         'arf
         (fn (x y z something)
             (do-something-else something x y z)))
    (def foo-replace-method (s f)
      (= (methods s) f))
    ; so external code can determine the local variables
    (def foo-get-private-variables ()
      '(x y z))
    (def foo (x)
      (with (y nil z nil)
        (let invoker
             (fn (f rest)
               (apply f x y z rest))
        (fn (which-method)
          (aif
            (methods which-method)
               (fn rest (invoker it rest)))))))
Then a method redefining macro can be:

  (def lastcons (l)
    (if (cdr l)
        (lastcons:cdr l)
        l))
  (mac redef-meth (type meth params . body)
    (givens replacer (sym:string type "-replace-method")
            privates (eval:list:sym:string type "-get-private-variables")
            _ (= (cdr:lastcons privates) params)
      `(,replacer ,meth (fn ,privates ,@body))))
Note that foo-replace-method and foo-get-private-variables could be placed in a central global table or two instead.