Arc Forumnew | comments | leaders | submitlogin
3 points by fallintothis 5153 days ago | link | parent

Can anybody think of any situations where this overloading would cause problems?

Admittedly, I can't think of any, but the scope of the change makes me uncomfortable. For any function f, (sref f v k) turns into (f k v)? Seems heavy-handed.

An alternative is to use defset to special-case on prototypes, but that relies on knowing the name of your prototype object. So, you'd have to make the macro explicitly assign to a name and defset that, which is kind of ugly:

  (mac defproto (name parent . attrs)
    (w/uniq lookup
      `(let ,lookup (obj ,@attrs)

         (= ,name (fn (attr . args)
                    (if args
                        (= (,lookup attr) (car args))
                        (or (,lookup attr)
                            ((only .attr) ,parent)))))

         (defset ,name (attr)
           (w/uniq g
             (list (list g attr)
                   `(,',name ,g)
                   `(fn (val) (,',name ,g val)))))

         ,name)))

  arc> (defproto a nil x "foo")
  #<procedure: a>
  arc> (defproto b a   y "bar")
  #<procedure: b>
  arc> (defproto c b   z "qux")
  #<procedure: c>
  arc> (map [list _!x _!y _!z] (list a b c))
  (("foo" nil nil) ("foo" "bar" nil) ("foo" "bar" "qux"))
  arc> (= b!x "changed")
  "changed"
  arc> (list a!x b!x c!x)
  ("foo" "changed" "changed")
By separating out the setter logic, you could address the (a 'x 10) issue:

  (mac defproto (name parent . attrs)
      (w/uniq (lookup attr-setter)
        `(let ,lookup (obj ,@attrs)

           (= ,name
              (fn (attr (o default))
                (or (,lookup attr default)
                    ((only [_ attr default]) ,parent))))

           (= ,attr-setter
              (fn (attr val)
                (= (,lookup attr) val)))

           (defset ,name (attr)
             (w/uniq g
               (list (list g attr)
                     `(,',name ,g)
                     `(fn (val) (,',attr-setter ,g val)))))

           ,name)))

  arc> (defproto a nil x 5)
  #<procedure:zz>
  arc> (a 'x)
  5
  arc> (a 'x 10)
  5
  arc> (a 'y)
  nil
  arc> (a 'y 10)
  10
  arc> (a 'y)
  nil
I'm not sure how to address the issue of using fns as protoypes. As Arc's type system stands, there may not be a much better way.


1 point by Pauan 5152 days ago | link

Hm... looks like I won't be able to transparently integrate it into Arc without changing ac.scm. I could try using defcall from Anarki, though.

-----