Arc Forumnew | comments | leaders | submitlogin
Last call for Arc bugs
10 points by pg 5511 days ago | 34 comments
I think we've fixed all the actual bugs supplied in our call for bugs ( Thanks, everyone. If there's anything more anyone wants fixed, please let us know, because we hope to do a new release soon.

The main point of the release is to push out a significantly better implementation of News, but we want to clean up any outstanding problems with Arc itself while we're at it.

5 points by CatDancer 5510 days ago | link

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))
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 5509 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 5509 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 5508 days ago | link

Thanks, we switched to this definition.


3 points by CatDancer 5508 days ago | link

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


3 points by thaddeus 5511 days ago | link

Not sure if you missed this one ?

I didn't see a reply so I am not sure if you decided these were bugs or not.

Thanks, T.


4 points by pg 5511 days ago | link

For now I'm going to leave Windows ports as something for other people to do downstream if they want to. It should be pretty easy, and I don't want to do it myself because I don't have access to a Windows machine or understand anything about the OS.


6 points by kens 5511 days ago | link

Currently, ensure-dir and date use system to run Unix commands. It would be much more portable if they used mzscheme operations instead. This has caused me trouble not only on Windows, but different versions of Linux. And I think make-temporary-file could replace /dev/urandom.


3 points by pg 5509 days ago | link

I changed date to get the date from Mzscheme, but it's not so easy to change ensure-dir. Mz's make-directory doesn't create intermediate directories like mkdir -p, and I don't want to get into trying to understand pathnames.


2 points by thaddeus 5509 days ago | link

------------------------ In ac.scm

    1. added:
    (require (lib ""))

    2. added:
    (xdef 'make-directory make-directory)
    (xdef 'make-directory* make-directory*)
------------------------ In arc.arc (got from anarki)

    (def mkdir (path (o parents))
         (if (is parents nil)
             (make-directory path)
             (make-directory* path))

    (def ensure-dir (path)
        (unless (dir-exists path)
             (mkdir path t)))
I tested on Windows... (ensure-dir "C:/thaddeus/arc/thaddeus/thaddeus/")

Edited. T.


1 point by eds 5509 days ago | link

Here are the two patches for ensure-dir in Anarki stable:

According to the comment, there is a bug in MzScheme <371 which sets the sticky bit on *nix, so it may still be necessary to call system sometimes.


1 point by thaddeus 5509 days ago | link

don't forget these changes require mods for the $ usage (which you can probably cut out)

and (xdef 'which-os system-type).



1 point by CatDancer 5509 days ago | link

Oh right, now I remember the sticky bit problem!

. . . .


1 point by CatDancer 5509 days ago | link

If someone wants to implement this, make-directory* in the library ( looks like it might do it for you. But I haven't tried it myself (I'm not running Windows either).


2 points by CatDancer 5511 days ago | link

If anyone wants to take on being a distributor for a Windows port (or for different variants of Linux, for that matter), I do have a patch for date here:


2 points by eds 5510 days ago | link

Another option is the Anarki stable branch (, which has most of fixes necessary to make most of Arc work portably on Windows and other OSes. (And, being a bug-fix branch, the amount of other random material is limited.)


4 points by thaddeus 5510 days ago | link

I agree with the option, but I also think these posts will fall off the deep end in about 2 months. By then new members may only discover the option after they've discovered the problem. So we're not really saving new members wasted efforts unless the install page guides people.



2 points by pmarin 5510 days ago | link

Why not to setup some kind of wiki under The Tclers Wiki is a great example.


1 point by eds 5510 days ago | link

pg: Even if you'd rather not think about supporting Windows portability yourself, providing a link to the Anarki stable branch would help new Windows users. Finding this stuff on the forum after it's fallen off the top couple of pages is not very easy.


2 points by thaddeus 5511 days ago | link


I have most of them already fixed myself, with the exception of pipe-from, but an average person (aka me) with Windows OS is going to spend time both trying to get Arc working and sifting through the forum which isnt easily searchable (I had to sift through over 300 posts, with 80% of the content being way over my head, to determine pipe-from wasn't expected to be working for a specific reason.... had no clue what "dev/urandom" even was).

If I might suggest: if your not going to fix these that you start a known issues document to save people from the headaches and tail chasing. Even putting something on your install page noting that Windows isn't supported would be appreciated by newcomers.

[Edit] As an idea maybe we could have one posting thread for OS related issues that your install page has a link to ? ....



2 points by stevedekorte 5511 days ago | link

I wld rcmd usg a btr nming con-vnt fr fn nms.


5 points by dreish 5511 days ago | link

My tendons say no thanks.


3 points by stevedekorte 5510 days ago | link

Do you mean to write: my tnd sy no tks? ;)


2 points by dreish 5510 days ago | link

No, because I wouldn't expect you to invest the time needed to learn a cutesy language for a one-off thing like a comment. A programming language, on the other hand ...

To be more specific, though I like Clojure a lot, compare Clojure's defmacro to Arc's mac. (The names, not the designs.) Regardless of how you learn about "mac", whether from reading source code or documentation, "mac" is not likely to be mysterious. In context, it should be pretty clear you're defining a macro, even if you haven't seen many before. (It was for me, reading Arc code a couple of years ago and not having seen many Lisp macros before.)

If you write a lot of macros, you're typing an extra five characters over and over for the rest of your life.

I'd rather pay a cost up-front (in this case a ridiculously tiny one) to save thousands of keystrokes. Keystrokes I can use for other purposes, like writing comments here.

Of course, it would be easy to just make mac a macro that expands to defmacro, but I'm not sure I like the idea of creating a unique dialect of a language.


1 point by stevedekorte 5510 days ago | link

I suspect if you actually measure the increase in character count it's something like 1 extra character per 2 pages of code. If that makes a difference then maybe you should listen to your tendons. If you're typing more than a few pages of code a day, you're doing something wrong - most likely failing to properly abstract your code in one way or another.

I think the real reason for these obfuscations is that nerds like obfuscation. It makes them feel clever to understand something that looks confusing to the non-initiated.


7 points by pg 5509 days ago | link

The reason you want commonly used operators to be short is so that most of the information you see on your screen is the content of your program. It's the same point Tufte makes about data-ink ratio in graphs. Conversely, long names and required boilerplate are like the stuff he calls "chartjunk."

You see the same thing in math notation. Do you think mathematicians use an integral symbol instead of writing out the word "integral" because it makes them feel clever? I think it's because the resulting bloat would make math expressions harder to read, not easier.


2 points by stevedekorte 5509 days ago | link

I would agree that conciseness is a good reason to create a special symbol when it outweighs the cost of obfuscation and would only suggest measuring it and weighing the two instead of going with terseness by default.

For example, most equations have relatively few symbols and typically writing out "integral" might double that number. If it could be shown that "mac" vs. "macro" or "car" vs "first" halves your character count, then I think that would make a good case for their use. But if it only reduces the character count by a few percent or less, then AFAICS, it's not a reasonable tradeoff and can only guess that readability isn't the underlying motivation.


3 points by thaddeus 5509 days ago | link

Initially I tried to make operator/variable names descriptive, but as time went on I became tired of typing every descriptive name again and again so, obviously, I tried to establish a balance between readability and convenience... However, the more I code the more I notice the names become shorter and find it takes effort to achieve meaningful names. That balance is going to be different person to person, but I will hazard a guess that the more you code the shorter the names become.

as an example (not that the function works):

    (def fill (table-name with)
         (filltable table-name with))

    (def fillcup (with size)
        (let cup size
            (fill cup with)))

    (fillcup "coffee" 8oz*)
The above is ideally how I would name names, but then find myself trying to incorporate the data type into the name...

    (def fillcup (with-string size-table)
        (let cup size-table
            (fill cup with-string)))
which I think is equally as bad as:

    (def fillcup (s tb)
        (let cup tb
            (fill cup s)))
This last one is bad as 'tb' may tell it's a table, but what is it conceptually? A size table...

So here are my options:

    * the idealized version isn't descriptive enough
    * if all my code were fully descriptive I would be
      worse off reading and typing everything.
    * the short form is just as bad as both the idealized
      version and the descriptive version.
So it doesn't surprise me that people go with the short form, the lesser of evils - perhaps ?

The worst part is that because all the options suck I end up doing things like:

    (def fillcup (with-str size-tb)
        (let cup size-tb
            (fill cup with-str)))
Which by then I hate my code and should have just stuck with the idealized or the short.

I personally wish there were a means to quickly identify the data-type without having to incorporate it into the name, something like a hover tag - this would, more often, allow myself to afford the meaningful without being overly descriptive.

(I currently use textmate to write code and the terminal for the repl).

Just and opinion from a hobby programmer with only a few hundred hours programming experience.



2 points by conanite 5509 days ago | link

Have a look at ... you might find it reeks of arrogance, or you might enjoy it:

"The sticking point is compression-tolerance. As you write code through your career, especially if it's code spanning very different languages and problem domains, your tolerance for code compression increases. It's no different from the progression from reading children's books with giant text to increasingly complex novels with smaller text and bigger words."

If my understanding is vaguely correct, Yegge argues for compact code for the same reasons pg does.

I personally wish there were a means to quickly identify the data-type

Something that an editor for a dynamic language can give you is run-time analysis of your code - so, indeed, a mouse-over could in fact give you a list of the types assigned to any given symbol. This is something I'd love to get welder to do ... it's entirely possible, in theory :)

Alternatively, you could write your own function definition macro that lets you specify param types and checks them for you at runtime:

  (typed-fn fillcup ((string with) (table size)) 
    (let ...
But my tendons recoil in horror at the implications of this. Remember: strong typing hurts your keyboard!


2 points by thaddeus 5509 days ago | link

I enjoyed the first half - then he went on and on and on....

My goal is to try making code readable enough that documentation or 'metadata' is barely needed. I'm going to rework my code and start keeping my code idealized - not descriptive - not short.

I'm going see how it works when I drop the data type tagging all together and hope one day when I am a little more knowledgeable I will be able to craft a solution.

Maybe in a few years I'll let you know how it went :) T


1 point by applepie 5507 days ago | link

I think I may have lost my faith in Arc.

But the comparison with math notation was enlightening.

You definitely have a point.


1 point by eds 5511 days ago | link

Not a huge issue, but there is


1 point by eds 5511 days ago | link

Thanks for responding


1 point by wheels 5508 days ago | link

As I recall the line numbers that come back from the interpreter when there are errors in the code were all munged; that and better support for just "load up this file and run it" would be nice. Oh, and the RSS fix would be neat. :-)