Arc Forumnew | comments | leaders | submitlogin
5 points by CatDancer 5657 days ago | link | parent

Aha, I finally realized that with respect to my specific complaint of obj expanding into uses of atomic, there's no need to protect the setting of the values in the table with atomic since the newly created table will not be visible to other threads at least until obj returns. The fix is easy:

   (mac obj args
     (w/uniq g
       `(let ,g (table)
  -       ,@(map (fn ((k v)) `(= (,g ',k) ,v))
  +       ,@(map (fn ((k v)) `(sref ,g ,v ',k))
                 (pair args))
          ,g)))
with this (catch (obj a (throw nil))) now works and there's no danger that doing something like (obj a (readfile "foo")) will hang other threads.


5 points by CatDancer 5657 days ago | link

A third perspective is that the bug isn't in the use of =, but that obj evaluates its value arguments too late.

In a function call

  (f (g) (h))
g and h are evaluated before f is called. A user might expect obj to work the same way for its value arguments (though, as a macro, of course it doesn't have to):

  (obj a (g) b (h))
This expectation can be fulfilled by evaluating the value arguments before storing them in the table. The existing macro could be modified to do that, though perhaps this implementation would be simpler:

  (mac obj args
    `(listtab (list ,@(map (fn ((k v))
                             `(list ',k ,v))
                           (pair args)))))
codetree of the arc2 obj definition => 48 this definition => 36

-----

3 points by CatDancer 5656 days ago | link

If we allow table to take arguments to populate the table...

  -(xdef 'table (lambda () (make-hash-table 'equal)))
  +(xdef 'make-table (lambda () (make-hash-table 'equal)))

  -(set setter (table))
  +(set setter (make-table))

  ;; inserted before "def memo"

  +(def table args
  +  (let h (make-table)
  +    (map (fn ((k v)) (= (h k) v))
  +         (pair args))
  +    h))

  arc> (table 'a 1 'b 2)
  #hash((a . 1) (b . 2))
then the definitions of obj and listtab are simplified:

  (mac obj args
    `(table ,@(mappend (fn ((k v))
                         (list (list 'quote k) v))
                       (pair args))))

  arc> (macex1 '(obj a 1))
  (table (quote a) 1)

  (def listtab (al)
    (apply table (apply + '() al)))
and the value arguments to obj are evaluated early, like a function call, so there are no problems with atomic.

-----

2 points by pg 5655 days ago | link

Thanks, we switched to this definition.

-----

3 points by CatDancer 5655 days ago | link

Wow, it's a pretty good deal for me to get my patches tested by thousands of HN users! ^___^

-----