Arc Forumnew | comments | leaders | submit | drcode's commentslogin

Thanks for this- I'm actually writing a Python interpreter in Coffeescript right now, so the Norvig interpreter and this coffeescript version are a great reference to compare against!


1 point by evanrmurphy 3747 days ago | link

> I'm actually writing a Python interpreter in Coffeescript

How intriguing! What got you interested in this project, if you don't mind my asking?


6 points by drcode 4271 days ago | link | parent | on: Question: What are Arc's strengths?

1. Brevity is top priority. If you learn all the arc functions there are lots of clever commands that anticipate common programming idioms and allow you to write very pithy code.

2. Encourages 50:50 mix of functional and imperative code for what each does best- See the accum command for an example. (If you implement this in clojure, be sure to use the new transients feature

3. The design of the web server is elegant (though still somewhat alpha)

4. Call/cc is available (this is the one thing you won't be able to implement in clojure, unless you're some kind of super-guru :-)

5. Intrasymbol syntax is a really promising idea that still needs to be fleshed out a bit.

6. Simplicity- The code behind arc (i.e. the files ac.scm and arc.arc) are, by design, is extremely simple (much simpler than clojure)

IMHO, the value of arc to someone not interested specifically in language design is lower now that Clojure is available. Clojure took many good ideas from arc and expanded on them in a way that really cut into arc's value proposition.

I still think pg's rule of "brevity, brevity, brevity" is the right approach in the long run- Hopefully someone will find time to take the best of these two Lisp dialects and create a new language in the future that rethinks "brevity" in terms of the ideas behind Clojure. (I'm think it'll take more than just a library of macros and functions to do this)


2 points by lojic 4271 days ago | link

I really have mixed emotions regarding the two approaches of building on the JVM vs. building from scratch.

On the one hand, building on top of the JVM gives quite a head start in many ways, and I think it's a bit ridiculous how poor the interop situation is for native programs despite the availability of FFIs (although some/much of this may be fundamental to language differences).

On the other hand, it seems the least common denominator problem always creeps up when building on a VM plus you have an extra dependency in the chain, etc.

If the Y axis is features and the X axis is time, it seems clear that building on a VM gives you a higher Y intercept. The question is whether the slope is unduly impeded. I suspect it might be, but that's totally subjective on my part.


1 point by lg 4270 days ago | link

>Hopefully someone will find time to take the best of these two Lisp dialects and create a new language in the future that rethinks "brevity" in terms of the ideas behind Clojure.

I'm curious which particular ideas you're talking about? I've used both and I don't know what clojure brings to the table that arc really needs, besides the stuff that arc will certainly get anyway, like libraries, some kind of module system, and facilities for performance tuning. (Although I think clojure could use some better libraries, too :)


1 point by devlinsf 4270 days ago | link

Hmm... I'm interested in points 4 & 5 specifically. Could someone offer an explanation/post some good links?


4 points by fallintothis 4270 days ago | link

First-class continuations & call/cc are notoriously difficult to explain (and indeed, can be hard to understand in code that uses them). Your best bet is to Google around for info, seeing if you can make sense of the (vast) material available. and might be good starts.

As for point 5, Arc uses certain characters as syntax abbreviations iff the special characters occur in what would otherwise be normal symbols (to the Scheme reader). So far, there's

  .a    ; is the same as (get a)
  a.b   ; is the same as (a b)
  !a    ; is the same as (get 'a)
  a!b   ; is the same as (a 'b)
  f&g   ; is the same as (andf f g)
  f:g   ; is the same as (compose f g)
  ~f    ; is the same as (complement f)

  ((get a) b)        ; is the same as (b a) by Arc's indexing
                     ; e.g., ("abc" 0) is #\a
  ((andf f g) x)     ; is the same as (and (f x) (g x))
  ((compose f g) x)  ; is the same as (f (g x))
  ((complement f) x) ; is the same as (no (f x))
See arc.arc for the actual definitions of these operators.

There are precedence and associativity rules, such as

  a!b.c ; is the same as ((a 'b) c) because ! and . are 
        ; left-associative
  f:g:h ; is the same as (compose f g h)
  ~f:g  ; is the same as (compose (complement f) g)
To explore these more, you can use the ssexpand function in Arc:

  arc> (ssexpand 'a:b.c!d)
  (compose a b.c!d)
  arc> (ssexpand 'b.c!d)
  ((b c) (quote d))


2 points by conanite 4270 days ago | link

call/cc, (or ccc in arc) isn't actually used very much in the official distribution, except to provide escape routines, à la

    (each x xs 
      (if (foo x) 
          (throw x))))
so you don't need to go all the way to the end of a loop.

The last time I looked, ccc isn't used to capture and re-use first-class continuation objects except for this escape-clause purpose.

Here's a fine article on the subject -

And here's a long-winded, verbose, java-oriented article I wrote last year in an attempt to explain ccc in java terms -


1 point by conanite 4270 days ago | link

On top of that, while we're on the topic, I don't know what happens if you jump into another continuation in the following circumstances:

1. you're inside atomic-invoke, call-w/stdout, call-w/stdin, or anything that creates context that needs to be undone on the way out. The problem is that a continuation from in here can be exited multiple times although it was entered only once.

2. similarly, you're inside protect, (equivalent to "finally" in java) - is the "after"-fn called, and if so, only once or for each re-entered continuation?

3. the continuation you jump into was originally running on another thread.

I should write tests to figure out what happens in all these cases, but if anybody knows the answers I can live with being lazy :)

With all these questions, I can only echo fallintothis' remark that continuations are notoriously difficult to explain, and while they make for some great intellectual amusement (see Mondo Bizarro - and ), they're not practical for everyday coding.


1 point by tumult 4268 days ago | link

This is what dynamic-wind is for.

(dynamic-wind is one of the coolest things ever)


4 points by drcode 4347 days ago | link | parent | on: Arc presentation

good job- I think it really gets the point across in showing the value of macros to a blub programmer.


3 points by drcode 4352 days ago | link | parent | on: Thank you pg and rtm!

I have to agree- arc is pretty awesome- Hope it continues evolving and stays open to new ideas!


2 points by drcode 4368 days ago | link | parent | on: Request for Bugs



2 points by conanite 4368 days ago | link



4 points by drcode 4369 days ago | link | parent | on: Request for Bugs

  arc> (= foo (obj a (obj x 1)))
  #hash((a . #hash((x . 1))))
  arc> (= ((foo 'a) 'x) 8)
  arc> (= (foo!a 'x) 7) 
  Error: "Can't invert  ((foo (quote a)) (quote x))"
I would argue that the fact that you can't just say foo!a!x is a borderline bug, as well.

Also, I wish this would work right:

  (map `[x _ z] '(1 2 3))
It should give the same result as (map [list 'x _ 'y] '(1 2 3))

Some primitive data types leak scheme internals when printed, such as hash tables- I would call this a bug.

Also, all datatypes should really be readable. For instance,

   (read (tostring (pr (obj a 1 b 2))))
should not give an error.

As an aside, if you haven't looked at the map/vector syntax in clojure you really should... The fact that you can write [1 2 (+ x 1)] to yield the same result as (list 1 2 (+ x 1)) or `(1 2 ,(+ x 1)) is very compact, clever and useful for writing succinct code.

(It'll create a vector not a list of course, but that's orthogonal to my point, since all clojure sequence functions can use these two interchangeably)


4 points by pg 4359 days ago | link

Looks like the first can be fixed thus:

    (def expand-metafn-call (f args)
      (if (is (car f) 'compose)
           ((afn (fs)
              (if (caris (car fs) 'compose)            ; nested compose
                   (self (join (cdr (car fs)) (cdr fs)))
                  (cdr fs)
                   (list (car fs) (self (cdr fs)))
                  (cons (car fs) args)))
            (cdr f))
          (is (car f) 'no)
           (err "Can't invert " (cons f args))
           (cons f args)))


2 points by CatDancer 4368 days ago | link

Here's a patch against arc2 which implements reading and writing tables:


1 point by drcode 4457 days ago | link | parent | on: Arc presentation

Do you live in MN? (I'm visiting there beginning of March...)


1 point by projectileboy 4455 days ago | link

Yeah! See my profile for more info.


15 points by drcode 4465 days ago | link | parent | on: Happy birthday, Arc

Surprise! I brought a cake:

               ()() ()()                 
                # # # # 
             {_` ` ` ` `_}
           {_  H A P P Y  _}
         {_ B I R T H D A Y _}
    (   `"""""""""""""""""""""`   ) 


7 points by conanite 4465 days ago | link

It's a beautiful cake. But doesn't it have too many candles?


2 points by drcode 4502 days ago | link | parent | on: Ask Arc: does code have to be text?

I think the answer is simple: If you allow non-ascii characters in a lisp, it would only "feel" right if the characters were fully programmable, as opposed to just adding a handful of extra characters. Lisp users don't like new features if they aren't fully programmable- You should be able to declare a new symbol in lisp code somehow and then be able to use it, IMHO. This, however, is non-trivial to implement (though I've had some ideas about this that I've been wanting to code up for years but haven't had time to do yet...)


1 point by CatDancer 4502 days ago | link

What does "fully programmable" mean?


1 point by drcode 4501 days ago | link

By that I mean if you define a table library, you should be able to write code that allows the data of a table appear like a table, with a grid and everything, right within your code editor. That's what I would mean with "fully programmable"


1 point by CatDancer 4500 days ago | link

When you say you want "characters to be fully programmable" does this mean that if you had "fully programmable characters" you'd be able to edit tables in your code editor as you describe, or are you making an analogy saying that you'd want characters to be fully programmable like these tables are fully programmable?


2 points by drcode 4496 days ago | link

The former- I'm saying that if you're going to allow more characters, I'd want to go all the way and have an editor that is part of the "language definition" that supports arbitrary graphics and ui elements that is controllable through the language in a "lisp like" way and would allow code appearance to be 100% customizable right inside the code.


1 point by zitterbewegung 4493 days ago | link

You mean redefine the reader and have reader macros?


1 point by jonnytran 4492 days ago | link

No, I think what people are getting at is... why does program source have to be represented by only ASCII text? After all, if code is data, an IDE is just a data editor, where that data happens to be code.

I think it has been shown many times throughout history that notation matters. In fact, the entire concept of Arc is based on this principle. Otherwise, Common Lisp would be suitable.


1 point by justsomeone 4487 days ago | link

Why does it have to be ASCII? No reason, The simplest answer may just be that the language writer feels that adding UTF-8, or UTF-16, support would be a waste of their time, or is below them. As for programming IN the language, it becomes a matter of what is easy for the programmer to type. In a way, this whole thing is a matter of deciding what is the lowest common denominator that one wants to support.


1 point by CatDancer 4495 days ago | link

"allow"? ^_^


10 points by drcode 4502 days ago | link | parent | on: My favorite debug print macro

I would also point out that you can use a colon, which means you don't have to muck with parenthesis when inserting/removing the debugging code:

  (+ 3 (erp:/ 4 2) 5)


3 points by CatDancer 4502 days ago | link

Very nifty!