100 Languages Speedrun: Episode 13: Arc
Tags: arc, lisp
Published: 2021-12-02 22:44:18

[Arc language](https://en.wikipedia.org/wiki/Arc_(programming_language)) was supposed to be the new revolutionary dialect of Lisp. It was created by Paul Graham, got a lot of publicity, and then completely fizzled out. As far as we know, Hacker News website is the only notable program written in Arc.

The original Arc seems pretty much abandoned, and doesn't even have ability to execute a file - it's just a REPL (from which you could presumably loan files).

I'll be using [Anarki fork](https://github.com/arclanguage/anarki). Anarki is also a very poor experience. Installation takes a lot of complicated steps, and any script takes literally 20s to start. But let's ignore all those issues and focus on the language itself.

### Hello, World!

```scheme
(prn "Hello, World!")
```

`prn` is short for "PRint, with Newline". Arc is quite extreme at using very short and cryptic names for everything, in times when most languages prefer longer and more descriptive names.

### FizzBuzz

```scheme
; fizzbuzz in arc
(up n 1 100
  (prn (if
    (multiple n 15) 'FizzBuzz
    (multiple n 5) 'Buzz
    (multiple n 3) 'Fizz
    n)))
```

If you can navigate all the parentheses, it's straightforward enough.

`(multiple n 5)` returns true or false depending on whether `n` is divisible by 5. It's super useful for writing FizzBuzz, and pretty much nothing else, but hey, at least 10% of all programs are Hello, World!, FizzBuzz, and such.

All right, that's not even true. It returns `t` or `nil`, because having types for `true` or `false` is too complicated somehow? This isn't Arc specific, some old Lisps did that, but I thought by now we moved beyond this stuff.

The nice thing is that `if` is an expression, and it does the whole `if/else-if/else-if/else` chain.

Range for loop uses cryptic `up`. I tried `for`, but there was some note about incompatibility between Anarki and Base Arc as `for` works differently between them, and Anarki `up` is essentially Arc Base `for`. That's a bit surprising for something so basic.

### Fibonacci

```scheme
(def fib (n)
  (if (<= n 2)
      1
    (+ (fib (- n 1))
       (fib (- n 2)))))

(up n 1 30
  (prn (fib n)))
```

Nothing too crazy here. `(def name (args) body)` defines a function. No explicit `return` is needed, as everything is an expression.

### Input

Arc has basically no documentation, so I had to dig through the source code to find out `(readline)` function. Which doesn't even work in REPL mode.

Arc doesn't have any way to create new variable in current binding - local variables go in another indentation level, which is unbelievably annoying thing a lot of Lisps do. That's not necessary - some Lisps like RLisp support normal variables - and many other functional languages let you define new variables in current scope. So far it seems that Arc just shares every possible design mistake with 1950s early bad Lisps.

```scheme
(prn "What is your name?")
(let name (readline)
  (prn "Hello, " name "!")
)
```

Which does what you'd expect, except really slowly:

```
$ ~/anarki/arc.sh ./input.arc
initializing arc.. (may take a minute)
What is your name?
Cat
Hello, Cat!
```

### Macros

Well, it wouldn't be a Lisp without macros. Arc doesn't introduce any new concepts, as far as I can tell these are just boring Common Lisp style macros.

```
(mac oddeven (v ifeven ifodd)
  `(if (even ,v) ,ifeven ,ifodd))

(prn "Choose a number?")
(let number (int (readline))
  (oddeven number
    (prn number " is even")
    (prn number " is odd"))
)
```

Here's a macro that's does something when `number` is even, and something else when it's odd. In a language without macros we'd need to wrap `(prn number " is even")` in some kind of function.

In languages where such anonymous functions are easy to define, like Ruby blocks, you get 90% of that without needing any Lisp style macros.

Now to be fair, Lisp macros can do a lot beyond just saving you a few `(fn ...)`. The thing is, Arc doesn't bring anything new to the table.

### Should you use Arc?

No. Lisps are generally overrated, and Ruby style metaprogramming is far more approachable than any List macro system. But even if you want a Lisp, Arc is not even a top 10 choice among Lisps. It's also pretty much abandoned, all the versions.

### Code

[All code examples for the series will be in this repository](https://github.com/taw/100-languages-speedrun).

[Code for the Arc episode is available here](https://github.com/taw/100-languages-speedrun/tree/master/episode-13-arc).