Arc Forumnew | comments | leaders | submitlogin
Arc 3.1 (works on latest MzScheme)
43 points by pg 1914 days ago | 18 comments
With lots of help from Eli Barzilay (thanks, Eli!), Robert got Arc working on the latest version of Mzscheme.

You can get the latest code at

HN has been running this version for about a week. It seems to be a bit faster, maybe 10-20%.

There are a few other small changes. For example, intrasymbol + has been replaced by &. And these two bugs

have been fixed.

6 points by rntz 1914 days ago | link

Diff available here:

It seems that plt4's immutable conses have been worked around via low-level pointer hacking. I can only hope this doesn't introduce subtle bugs, but given that Eli Barzilay seems to work on plt scheme, hopefully this is not the case.

I've pushed the changes to anarki's "official" branch.


6 points by kens 1908 days ago | link

Thanks for fixing this! This was definitely not a trivial undertaking.

Now I can run Arc on the ARM-based SheevaPlug. (mzscheme 4.x has been ported to the ARM processor but mzscheme 372 had not.)


3 points by fallintothis 1912 days ago | link

I've updated my syntax highlighter & ftplugin with the new intrasymbol syntax, different/new Arc functions, and some other minor changes:

This resolves part of the issue from before ( For the full changeset, see


3 points by palsecam 1914 days ago | link

Really nice that it now works with the latest version! Always problematic to depend on old stuff IMHO.

Tested on Debian (Squeeze) with MzScheme 4.1.4 (the one in the official repositories), no problem :-)

Note: don't use 'mzscheme -m -f as.scm' but just 'mzscheme -f as.scm' instead (see "how-to-run-news").

For information, the 'coerce / 2.0 integer is fixed by defining an Arc integer (exint) as (and (integer? x) (exact? x)). The bug with dotted lists in quasiquote is fixed using a new small function 'imap, that is like 'map but "don't demand '()-terminated list".


2 points by lojic 1914 days ago | link

Can you summarize the principal changes required to work with an immutable cons ? I guess now that the files are versioned (thanks!) I can just do a diff, but if there are extensive changes, it might cause a Lisp newbie to miss the forest for the trees.


4 points by lojic 1914 days ago | link

In ac.scm

  ;; set a pointer to the cons cell, then dereference it as a pointer,
  ;; and bang the new value in the given offset
Hmm... so the fix was to "cast" the immutable cons cell to a mutable cons cell? Glad it works, but I was kind of hoping to learn that the immutable cons cell thing was workable for Arc. I guess I should read up on the MzScheme decision to make it immutable and see what pros/cons are associated with it.


1 point by soegaard 1913 days ago | link

See Flatt's blog post:

Further discussions can be found in the mail archive.


1 point by vegashacker 1913 days ago | link

Here's a post about it:


4 points by coconutrandom 1913 days ago | link

Oh wow!! I've been working on a small blog/forum in arc, and this new version reduced my local requests from ~140ms to ~60ms.

Thank you all very much for your work on this.


6 points by jefffoster 1914 days ago | link

As someone new to Arc, I had to do

mzscheme -f as.scm

To get this to run (without the -m) otherwise I got the message "main: not defined or required into the top-level environment"


5 points by adm 1914 days ago | link

hmmm...still no update in the tutorial.


10 points by garnet7 1913 days ago | link

Docs can make or break a free software project.


2 points by cronin1024 1913 days ago | link

If I remember correctly, Arc being tied to MzScheme was supposed to be a temporary thing, which I figured was the reason that Arc wasn't being ported to MzScheme 4.x. Does the work put into porting to 4.x mean that the official branch of Arc is going to stay tied to MzScheme for a good deal longer?


1 point by thaddeus 1913 days ago | link

~great; right when I get the ability to downvote, you strip it away for another 100 karma!

lol. no worries - I haven't used it anyway... T.

[EDIT] oh - and thanks for the upgrade - even though :)


1 point by herdrick 1913 days ago | link

Why is it faster? I would think that banning list mutation would only slow down a program that had originally used it.


5 points by rntz 1912 days ago | link

I presume arc3.1 is only faster if you use plt4, which is attributable to plt4 being faster than mzscheme 372 thanks to improvements to the language implementation. The speed boost obviously doesn't come from making conses immutable, since Arc still has mutable conses.

If you're asking why immutable conses could speed up a programming language in general, well, a compiler can make more powerful optimizations if it's allowed to assume that lists won't mutate mid-flight. Obviously a specific program that used mutability of conses would need to be rewritten, and might end up faster or slower; but code that doesn't take advantage of the mutability of conses (of which there is a lot, Scheme having the functional heritage it does) can be speeded up.

Of course, given that Arc's mutable conses are accomplished by using pointer hacking to mutate plt4's supposedly immutable conses, one would hope the plt4 compiler doesn't take real advantage of the immutability of their conses, otherwise it might make assumptions that Arc will break, leading to difficult-to-detect bugs.


1 point by herdrick 1911 days ago | link

Arc's mutable conses are accomplished by using pointer hacking to mutate plt4's supposedly immutable conses,



5 points by rntz 1911 days ago | link

  ; Eli's code to modify mzscheme-4's immutable pairs.

  ;; to avoid a malloc on every call, reuse a single pointer, but make
  ;; it thread-local to avoid races
  (define ptr (make-thread-cell #f))
  (define (get-ptr)
    (or (thread-cell-ref ptr)
        (let ([p (malloc _scheme 1)]) (thread-cell-set! ptr p) p)))

  ;; set a pointer to the cons cell, then dereference it as a pointer,
  ;; and bang the new value in the given offset
  (define (set-ca/dr! offset who p x)
    (if (pair? p)
      (let ([p* (get-ptr)])
        (ptr-set! p* _scheme p)
        (ptr-set! (ptr-ref p* _pointer 0) _scheme offset x))
      (raise-type-error who "pair" p)))

  (define (n-set-car! p x) (set-ca/dr! 1 'set-car! p x))
  (define (n-set-cdr! p x) (set-ca/dr! 2 'set-cdr! p x))
Really. (This is an excerpt from arc3.1's ac.scm.)