Cat’s hacks:

obj-no-atomic

  (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)))

Avoid unnecessary use of atomic by obj

Update: see http://arclanguage.org/item?id=9288 for an approach which fixes the bug of obj evaluating its value arguments too late, instead of working around the bug by avoiding =.

I use obj a lot in my code, using tables as objects/structs, and as I was condensing my code I began to get forms like:

 (obj a (if foo (throw nil) ...)

 (obj a (readfile "foo"))

obj expands into a call to = to store the individual values in the new table, and arc2 protects expansions of = with atomic. The first form above generates an error since the throw can’t cross the continuation boundary created by atomic, and the second is dangerous since any delay inside of a call to atomic will cause all other uses of atomic to hang until it is done.

However, in the case of obj there’s no need to protect the setting of the table values since the newly created table will not be visible to other threads at least until obj returns. Thus the creation of the table can be done outside of the protection of atomic.

With this patch the first form now works:

arc> (catch (obj a (throw nil)))
nil

And the second has no danger of hanging other threads.

Get This Hack

Apply This Hack to Your Arc

By using git or patch, you can incorporate this patch into your version of Arc.

With git

 $ git pull git://github.com/CatDancer/arc.git tag arc2.obj-no-atomic0

For example,

 $ mkdir arc
 $ cd arc
 $ git init
 $ git pull git://github.com/CatDancer/arc.git tag arc2.obj-no-atomic0

With patch

To apply this patch to your copy of arc using the patch command, download arc2.obj-no-atomic0.patch into your Arc directory, and at the Unix command line inside the Arc directory, type:

 patch <arc2.obj-no-atomic0.patch

patch” is a standard utility that comes with Unix. (If you’re running Windows, iirc patch comes with cygwin).

For example,

 $ wget http://ycombinator.com/arc/arc2.tar
 [... downloading ...]
 $ tar xf arc2.tar
 $ cd arc2
 $ patch <arc2.obj-no-atomic0.patch
 patching [...]
 $

License

The original Arc source is copyrighted by Paul Graham and Robert Morris and licensed under the Perl Foundations's Artistic License 2.0 as described in the “copyright” file in the Arc distribution.

My changes to Arc (this patch that I wrote) are in the public domain.

The combination of the original Arc and my changes together (what you get after you apply my patch) is also licensed under the Perl Foundations's Artistic License 2.0.